....................................../////.===Shadow-Here===./////................................................ > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < ------------------------------------------------------------------------------------------------------------------- /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// RIFF¤ WEBPVP8 ˜ ðÑ *ôô>‘HŸK¥¤"§£±¨àð enü¹%½_F‘åè¿2ºQú³íªú`N¿­3ÿƒügµJžaÿ¯ÿ°~¼ÎùnúîÞÖô•òíôÁÉß®Sm¥Ü/ ‡ó˜f£Ùà<˜„xëJ¢Ù€SO3x<ªÔ©4¿+ç¶A`q@Ì“Úñè™ÍÿJÌ´ª-˜ÆtÊÛL]Ïq*‘Ý”ì#ŸÌÏãY]@ê`¿ /ªfkØB4·®£ó z—Üw¥Pxù–ÞLШKÇN¾AkÙTf½è'‰g gÆv›Øuh~ a˜Z— ïj*á¥t d£“uÒ ¨`K˜¹ßþ]b>˜]_ÏÔ6W—è2r4x•íÖ…"ƒÖNîä!¦å Ú}ýxGøÌ —@ ;ÆÚŠ=ɾ1ý8lªË¥ô ^yf®Œ¢u&2©nÙÇ›ñÂñŒ³ aPo['½»øFùà­+4ê“$!lövlüÞ=;N®3ð‚õ›DÉKòÞ>ÄÍ ¥ˆuߤ#ˆ$6ù™¥îЇy’ÍB¼ çxÛ;X"WL£R÷͝*ó-¶Zu}º.s¸sšXqù–DþÿvªhüïwyŸ ¯é³lÀ:KCûÄ£Ëá\…­ ~—ýóî ¼ûûÜTÓüÇy…ŽÆvc»¾×U ñ¸žþоP÷¦ó:Ò¨¨5;Ð#&#ÖúñläÿÁœ GxÉ­/ñ‡áQðìYÉtÒw޼GÔ´zàÒò ð*ëzƒ•4~H]Ø‹f ñÓÈñ`NåWçs'ÆÏW^ø¹!XžµmQ5ÃËoLœÎ: ÞËÍ¥J ù…î èo£ßPÎñ¶ž8.Œ]ʵ~5›ÙË-ù*8ÙÖß±~ ©¹rÓê‚j¶d¸{^Q'˜±Crß ÚH—#¥¥QlÀ×ëã‡DÜ«èî þ&Çæžî;ŽÏºò6ÒLÃXy&ZŒ'j‚¢Ù€IßÚù+–MGi‰*jE€‘JcÜ ÓÌ EÏÚj]o˜ Þr <¾U ûŪæÍ/šÝH¥˜b”¼ ÁñßX GP›ï2›4WŠÏà×£…íÓk†¦H·ÅíMh–*nó÷à]ÁjCº€b7<ب‹¨5車bp2:Á[UªM„QŒçiNMa#<5›áËó¸HýÊ"…×Éw¹¦ì2º–x<›»a±¸3Weü®FÝ⑱ö–î–³|LPÈ~çð~Çå‡|º kD¢µÏàÆAI %1À% ¹Ò – ”ϝS¦‰4&¶£°à Öý”û_Ò Áw°A«Å€?mÇÛgHÉ/8)á¾ÛìáöŽP í¨PŸNÙµº¦‡§Ùš"ÿ«>+ªÕ`Ê÷‡‚ß Õû˜þãÇ-PÍ.¾XV‘€ dÜ"þ4¹ ±Oú‘©t¥¦FªÄÃÄ•b‚znýu½—#cDs˜ÃiÑOˆñ×QO=*IAÊ,¶ŽZƒ;‡wøXè%EÐk:F±Ú” .Ѽ+Áu&Ç`."pÈÉw o&¿dE6‘’EqTuK@Ì¥ã™À(Êk(h‰,H}RÀIXÛš3µ1©_OqÚÒJAñ$ÊÙÜ;D3çŒ[þùœh¬Ã³™ö6ç†NY".Ú‰ï[ªŸŒ '²Ð öø_¨ÂÉ9ué¶³ÒŠõTàîMØ#û¯gN‡bÙ놚X„ö …ÉeüÌ^J ‹€.œ$Æ)βÄeæW#óüßĺŸ€ ÀzwV 9oä»f4V*uB «Ë†¹ì¯žR霓æHXa=&“I4K;¯ç‹h×·"UŠ~<•╪Vêª&ÍSÃÆÅ?ÔqÎ*mTM ˜›µwêd#[C¡©§‘D<©àb†–ÁœøvH/,í:¯( ²£|4-„Æövv„Yͼ™^Á$ˆ„¢Û[6yB.åH*V¨æ?$=˜Ñ€•ñ·­(VlŸ‘ nÀt8W÷´Bûba?q9ú¶Xƒl«ÿ\ù¶’þòUÐj/õ¢Ìµ³g$ƒÎR!¸»|Oߍë’BhîÚÑ¢ñåŒJ„®„£2Ð3•ô02Nt…!£Í]Ïc½Qÿ?ˆ<&ÃA¾Ú,JˆijÌ#5yz„‰Î|ÊŽ5QÏ:‹ÐaóVÔxW—CpeÏzÐïíçôÿÅ_[hãsÐ_/ŽTÝ?BîˆííV$<¿i>²F¬_Eß¿ †bÊŒº­ÿ®Z H“C}”¬,Mp ý/Bá£w>˜YV°aƒúh+cŠ- r/[%|üUMHäQ°X»|û/@|°¥Ð !BÔ Ç¢Ä©š+Õì D«7ìN¶ŽðÔ " ƶ’ÖçtA‰Û×}{tþz­¾GÍ›k¹OEJR$ Â׃ «ëÁ"oÉôž$oUK(Ä)Ãz³Ê-‹êN[Ò3Œñbï8P 4ƒ×q¢bo|?<ÛX¬òÄͰL–±›(™ûG?ýË©ÚÄ–ÂDØÐ_Ç¡ô ¾–ÄÏø ×e8Ë©$ÄF¹Å‹ì[©óìl:F¾f´‹‹Xì²ï®\¬ôùƒ ÿat¥óèÒùHß0äe‚;ü×h:ÆWðHž=Ã8骣"kœ'Y?³}Tûè€>?0l›e1Lòñ„aæKÆw…hÖŠùW…ÈÆÄ0ši·›[pcwËþñiêíY/~-Á5˜!¿†A›™Mÿþ(±“t@â“ö2­´TG5yé]çå僳 .·ÍïçÝ7UÚ±Ð/Nè»,_Ï ùdj7\ï Wì4›„»c¸àešg#ÒÊ⥭áØo5‘?ÌdÝô¯ ¹kzsƒ=´#ëÉK›Ø´±-¥eW?‡çßtòTã…$Ý+qÿ±ƒ÷_3Ô¥í÷:æ–ž<·Ö‡‰Å¢ š‡%Ô—utÌÈìðžgÖÀz²À—ï÷Óîäõ{K'´È÷³yaÏÁjƒô}ž§®æÊydÕÈë5¯èˆõvÕ©ã*çD„ “z„Ó‡^^xÂ3M§A´JG‚öï 3W'ˆ.OvXè¡ÊÕª?5º7†˜(˜Ç¶#çê’¶!ÌdZK§æ 0fãaN]òY³RV ™î$®K2R¨`W!1Ôó\;Ý ýB%qæK•&ÓÈe9È0êI±žeŸß -ú@žQr¦ ö4»M¼Áè¹µmw 9 EÆE_°2ó„ŸXKWÁ×Hóì^´²GѝF©óäR†¦‰ç"V»eØ<3ùd3ÿÚ¤Žú“Gi" —‘_ÙËÎ~Üö¯¥½Î»üŸEÚŽåmÞþí ;ÞólËΦMzA"Âf(´òá;Éï(/7½ûñÌ­cïÕçлþÝz¾-ÍvÑ“pH­–ðÓj$¸Äû¤‚‘ãUBË-n“2åPkS5&‹Â|+g^œ®Ì͆d!OïäîU«c;{Û!ÅŽ«ëZ9Ókóˆ]¯ƒ›né `ÇÒ+tÆš (ØKá¾—=3œ®•vuMñg²\ï Ec€ 05±d™‡×iÇ×›UúvÌ¢£Èþ¡ÕØô¶ßÎA"ß±#Ö²ˆÊŸ¦*Ä~ij|àø.-¼'»Ú¥£h ofº¦‡VsR=N½„Î v˜Z*SÌ{=jÑB‹tê…;’HžH¯8–îDù8ñ¢|Q•bÛçš–‹m³“ê¨ åÏ^m¬Žãþ©ïêO‡½6] µÆ„Ooòü ²x}N¦Ë3ïé¿»€›HA˜m%çÞ/¿í7Fø“‹léUk)É°Œµ8Q8›:ÀŠeT*šõ~ôڝG6 ¢}`ùH­–”¡k ‰P1>š†®9z11!X wKfmÁ¦xÑ,N1Q”–æB¶M…ÒÃv6SMˆhU¬ÊPŽï‘öj=·CŒ¯u¹ƒVIЃsx4’ömÛýcå¡¶7ßŠß 57^\wÒÐÆ k§h,Œý î«q^R½3]J¸ÇðN ‚çU¬ôº^Áì} ³f©Õœ§ˆã:FÄÈ‚é(€™?àýÓüè1Gô£¼éj‚OÅñ  #>×—ßtà 0G¥Åa뀐kßhc™À_ÉñÞ#±)GD" YîäË-ÿÙ̪ ¹™a¯´¢E\ÝÒö‚;™„ë]_ p8‰o¡ñ+^÷ 3‘'dT4œŽ ðVë½° :¬víÑ«£tßÚS-3¶“þ2 †üüʨòrš¹M{É_¤`Û¨0ìjœøJ‡:÷ÃáZ˜†@GP&œÑDGÏs¡þ¦þDGú‘1Yá9Ôþ¼ ûø…§÷8&–ÜÑnÄ_m®^üÆ`;ÉVÁJ£?â€-ßê}suÍ2sõA NÌúA磸‘îÿÚ»ƒìö·á¿±tÑÐ"Tÿü˜[@/äj¬€uüªìù¥Ý˜á8Ý´sõj 8@rˆð äþZÇD®ÿUÏ2ùôõrBzÆÏÞž>Ì™xœ“ wiÎ×7_… ¸ \#€MɁV¶¥üÕÿPÔ9Z‡ø§É8#H:ƒ5ÀÝå9ÍIŒ5åKÙŠ÷qÄ>1AÈøžj"µÂд/ªnÀ qªã}"iŸBå˜ÓÛŽ¦…&ݧ;G@—³b¯“•"´4í¨ôM¨åñC‹ïùÉó¯ÓsSH2Ý@ßáM‡ˆKÀªÛUeø/4\gnm¥‹ŸŒ qÄ b9ÞwÒNÏ_4Ég³ú=܆‚´ •â¥õeíþkjz>éÚyU«Íӝ݃6"8/ø{=Ô¢»G¥ äUw°W«,ô—¿ãㆅү¢³xŠUû™yŒ (øSópÐ 9\åTâ»—*oG$/×ÍT†Y¿1¤Þ¢_‡ ¼ „±ÍçèSaÓ 3ÛMÁBkxs‰’R/¡¤ˆÙçª(*õ„üXÌ´ƒ E§´¬EF"Ù”R/ÐNyÆÂ^°?™6¡œïJ·±$§?º>ÖüœcNÌù¯G ‹ñ2ЁBB„^·úìaz¨k:#¨Æ¨8LÎõލ£^§S&cŒÐU€ü(‡F±Š¼&P>8ÙÁ ‰ p5?0ÊÆƒZl¸aô š¼¡}gÿ¶zÆC²¹¬ÎÖG*HB¡O<º2#ñŒAƒ–¡B˜´É$¥›É:FÀÔx¾u?XÜÏÓvN©RS{2ʈãk9rmP¼Qq̳ è¼ÐFׄ^¡Öì fE“F4A…!ì/…¦Lƒ… … $%´¾yã@CI¬ á—3PþBÏNÿ<ý°4Ü ËÃ#ØÍ~âW«rEñw‹eùMMHß²`¬Öó½íf³:‹k˜¯÷}Z!ã¿<¥,\#öµÀ¯aÒNÆIé,Ћ–lŽ#Àæ9ÀÒS·I’½-Ïp Äz¤Š Â* ­íÄ9­< h>׍3ZkËU¹§˜ŒŠ±f­’¤º³Q ÏB?‹#µíÃ¥®@(Gs«†vI¥Mµ‹Á©e~2ú³ÁP4ìÕi‚²Ê^ö@-DþÓàlÜOÍ]n"µã:žpsŽ¢:! Aõ.ç~ÓBûH÷JCÌ]õVƒd «ú´QÙEA–¯¯Œ!.ˆˆëQ±ù œ·Ì!Õâ )ùL„ÅÀlÚè5@B…o´Æ¸XÓ&Û…O«˜”_#‡ƒ„ûÈt!¤ÁÏ›ÎÝŠ?c9 â\>lÓÁVÄÑ™£eØY]:fÝ–—ù+p{™ðè û³”g±OƒÚSù£áÁÊ„ä,ï7š²G ÕÌBk)~ÑiCµ|h#u¤¶îK¨² #²vݯGãeÖ϶ú…¾múÀ¶þÔñ‚Š9'^($¤§ò “š½{éúp÷J›ušS¹áªCÂubÃH9™D™/ZöØÁ‡¦ÝÙŸ·kð*_”.C‹{áXó€‡c¡c€§/šò/&éš÷,àéJþ‰X›fµ“C¨œ®r¬"kL‰Â_q…Z–.ÉL~O µ›zn‚¹À¦Öª7\àHµšÖ %»ÇníV[¥*Õ;ƒ#½¾HK-ÖIÊdÏEÚ#=o÷Óò³´Š: Ç?{¾+9›–‘OEáU·S€˜j"ÄaÜ ŒÛWt› á–c#a»pÔZÞdŽtWê=9éöÊ¢µ~ ë ;Öe‡Œ®:bî3±ýê¢wà¼îpêñ¹¾4 zc¾ðÖÿzdêŒÑÒŝÀ‰s6¤í³ÎÙB¿OZ”+F¤á‡3@Ñëäg©·Ž ˆèª<ù@É{&S„œÕúÀA)‰h:YÀ5^ÂÓŒ°õäU\ ùËÍû#²?Xe¬tu‰^zÒÔãë¼ÛWtEtû …‚g¶Úüâî*moGè¨7%u!]PhÏd™Ý%Îx: VÒ¦ôÊD3ÀŽKÛËãvÆî…N¯ä>Eró–ð`5 Œ%u5XkñÌ*NU%¶áœÊ:Qÿú»“úzyÏ6å-၇¾ ´ ÒÊ]y žO‘w2Äøæ…H’²f±ÎÇ.ª|¥'gîV•Ü .̘¯€šòü¤U~Ù†*¢!?ò wý,}´°ÔÞnïoKq5µb!áÓ3"vAßH¡³¡·G(ÐÎ0Îò¼MG!/ài®@—¬04*`…«é8ªøøló“ˆÊ”èù¤…ßÊoÿé'ËuÌÖ5×È¡§ˆˆfŽë9}hìâ_!!¯  B&Ëö¶‰ÀAÙNVŸ Wh›¸®XÑJì¨ú“¿÷3uj²˜¨ÍÎìë±aúŠÝå¯ð*Ó¨ôJ“yºØ)m°WýOè68†ŸÏ2—‰Ïüꪫٚ¥‹l1 ø ÏÄFjêµvÌbü¦èÝx:X±¢H=MÐß—,ˆÉÇ´(9ú¾^ÅÚ4¿m‡$âX‘å%(AlZo@½¨UOÌÕ”1ø¸jÎÀÃÃ_ µ‘Ü.œº¦Ut: Æï’!=¯uwû#,“pþÇúŒø(é@?³ü¥‘Mo §—s@Œ#)§ŒùkL}NOÆêA›¸~r½¼ÙA—HJ«eˆÖ´*¡ÓpÌŸö.m<-"³ûÈ$¬_6­åf£ïÚâj1y§ÕJ½@dÞÁr&Í\Z%D£Íñ·AZ Û³øüd/ªAi†/Й~  ‡âĮҮÏh§°b—›Û«mJžòG'[ÈYýŒ¦9psl ýÁ ®±f¦x,‰½tN ‚Xª9 ÙÖH.«Lo0×?͹m¡å†Ѽ+›2ƒF ±Ê8 7Hցϓ²Æ–m9…òŸï]Â1äN†VLâCˆU .ÿ‰Ts +ÅÎx(%¦u]6AF Š ØF鈄‘ |¢¶c±soŒ/t[a¾–û:s·`i햍ê›ËchÈ…8ßÀUÜewŒðNOƒõD%q#éû\9¤x¹&UE×G¥ Í—™$ð E6-‡¼!ýpãÔM˜ Âsìe¯ñµK¢Ç¡ùôléœ4Ö£”À Š®Ðc ^¨À}ÙËŸ§›ºê{ÊuÉC ×Sr€¤’fÉ*j!úÓ’Gsùìoîßîn%ò· àc Wp÷$¨˜)û»H ×8ŽÒ€Zj¤3ÀÙºY'Ql¦py{-6íÔCeiØp‘‡XÊîÆUߢ܂ž£Xé¼Y8þ©ëgñß}é.ÎógÒ„ÃØËø¯»™§Xýy M%@NŠ À(~áÐvu7&•,Ù˜ó€uP‡^^®=_E„jt’ 403WebShell
403Webshell
Server IP : 41.207.40.59  /  Your IP : 216.73.216.58
Web Server : Apache/2.4.52 (Ubuntu)
System : Linux srv-prod 5.15.0-157-generic #167-Ubuntu SMP Wed Sep 17 21:35:53 UTC 2025 x86_64
User : www-data ( 33)
PHP Version : 8.3.26
Disable Function : NONE
MySQL : OFF  |  cURL : ON  |  WGET : ON  |  Perl : ON  |  Python : OFF  |  Sudo : ON  |  Pkexec : ON
Directory :  /var/www/html/formation/user/classes/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ Back ]     

Current File : /var/www/html/formation/user/classes/fields.php
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.

namespace core_user;

use core_text;

/**
 * Class for retrieving information about user fields that are needed for displaying user identity.
 *
 * @package core_user
 */
class fields {
    /** @var string Prefix used to identify custom profile fields */
    const PROFILE_FIELD_PREFIX = 'profile_field_';
    /** @var string Regular expression used to match a field name against the prefix */
    const PROFILE_FIELD_REGEX = '~^' . self::PROFILE_FIELD_PREFIX . '(.*)$~';

    /** @var int All fields required to display user's identity, based on server configuration */
    const PURPOSE_IDENTITY = 0;
    /** @var int All fields required to display a user picture */
    const PURPOSE_USERPIC = 1;
    /** @var int All fields required for somebody's name */
    const PURPOSE_NAME = 2;
    /** @var int Field required by custom include list */
    const CUSTOM_INCLUDE = 3;

    /** @var \context|null Context in use */
    protected $context;

    /** @var bool True to allow custom user fields */
    protected $allowcustom;

    /** @var bool[] Array of purposes (from PURPOSE_xx to true/false) */
    protected $purposes;

    /** @var string[] List of extra fields to include */
    protected $include;

    /** @var string[] List of fields to exclude */
    protected $exclude;

    /** @var int Unique identifier for different queries generated in same request */
    protected static $uniqueidentifier = 1;

    /** @var array|null Associative array from field => array of purposes it was used for => true */
    protected $fields = null;

    /**
     * Protected constructor - use one of the for_xx methods to create an object.
     *
     * @param int $purpose Initial purpose for object or -1 for none
     */
    protected function __construct(int $purpose = -1) {
        $this->purposes = [
            self::PURPOSE_IDENTITY => false,
            self::PURPOSE_USERPIC => false,
            self::PURPOSE_NAME => false,
        ];
        if ($purpose != -1) {
            $this->purposes[$purpose] = true;
        }
        $this->include = [];
        $this->exclude = [];
        $this->context = null;
        $this->allowcustom = true;
    }

    /**
     * Constructs an empty user fields object to get arbitrary user fields.
     *
     * You can add fields to retrieve with the including() function.
     *
     * @return fields User fields object ready for use
     */
    public static function empty(): fields {
        return new fields();
    }

    /**
     * Constructs a user fields object to get identity information for display.
     *
     * The function does all the required capability checks to see if the current user is allowed
     * to see them in the specified context. You can pass context null to get all the fields without
     * checking permissions.
     *
     * If the code can only handle fields in the main user table, and not custom profile fields,
     * then set $allowcustom to false.
     *
     * Note: After constructing the object you can use the ->with_xx, ->including, and ->excluding
     * functions to control the required fields in more detail. For example:
     *
     * $fields = fields::for_identity($context)->with_userpic()->excluding('email');
     *
     * @param \context|null $context Context; if supplied, includes only fields the current user should see
     * @param bool $allowcustom If true, custom profile fields may be included
     * @return fields User fields object ready for use
     */
    public static function for_identity(?\context $context, bool $allowcustom = true): fields {
        $fields = new fields(self::PURPOSE_IDENTITY);
        $fields->context = $context;
        $fields->allowcustom = $allowcustom;
        return $fields;
    }

    /**
     * Constructs a user fields object to get information required for displaying a user picture.
     *
     * Note: After constructing the object you can use the ->with_xx, ->including, and ->excluding
     * functions to control the required fields in more detail. For example:
     *
     * $fields = fields::for_userpic()->with_name()->excluding('email');
     *
     * @return fields User fields object ready for use
     */
    public static function for_userpic(): fields {
        return new fields(self::PURPOSE_USERPIC);
    }

    /**
     * Constructs a user fields object to get information required for displaying a user full name.
     *
     * Note: After constructing the object you can use the ->with_xx, ->including, and ->excluding
     * functions to control the required fields in more detail. For example:
     *
     * $fields = fields::for_name()->with_userpic()->excluding('email');
     *
     * @return fields User fields object ready for use
     */
    public static function for_name(): fields {
        return new fields(self::PURPOSE_NAME);
    }

    /**
     * On an existing fields object, adds the fields required for displaying user pictures.
     *
     * @return $this Same object for chaining function calls
     */
    public function with_userpic(): fields {
        $this->purposes[self::PURPOSE_USERPIC] = true;
        return $this;
    }

    /**
     * On an existing fields object, adds the fields required for displaying user full names.
     *
     * @return $this Same object for chaining function calls
     */
    public function with_name(): fields {
        $this->purposes[self::PURPOSE_NAME] = true;
        return $this;
    }

    /**
     * On an existing fields object, adds the fields required for displaying user identity.
     *
     * The function does all the required capability checks to see if the current user is allowed
     * to see them in the specified context. You can pass context null to get all the fields without
     * checking permissions.
     *
     * If the code can only handle fields in the main user table, and not custom profile fields,
     * then set $allowcustom to false.
     *
     * @param \context|null Context; if supplied, includes only fields the current user should see
     * @param bool $allowcustom If true, custom profile fields may be included
     * @return $this Same object for chaining function calls
     */
    public function with_identity(?\context $context, bool $allowcustom = true): fields {
        $this->context = $context;
        $this->allowcustom = $allowcustom;
        $this->purposes[self::PURPOSE_IDENTITY] = true;
        return $this;
    }

    /**
     * On an existing fields object, adds extra fields to be retrieved. You can specify either
     * fields from the user table e.g. 'email', or profile fields e.g. 'profile_field_height'.
     *
     * @param string ...$include One or more fields to add
     * @return $this Same object for chaining function calls
     */
    public function including(string ...$include): fields {
        $this->include = array_merge($this->include, $include);
        return $this;
    }

    /**
     * On an existing fields object, excludes fields from retrieval. You can specify either
     * fields from the user table e.g. 'email', or profile fields e.g. 'profile_field_height'.
     *
     * This is useful when constructing queries where your query already explicitly references
     * certain fields, so you don't want to retrieve them twice.
     *
     * @param string ...$exclude One or more fields to exclude
     * @return $this Same object for chaining function calls
     */
    public function excluding(...$exclude): fields {
        $this->exclude = array_merge($this->exclude, $exclude);
        return $this;
    }

    /**
     * Gets an array of all fields that are required for the specified purposes, also taking
     * into account the $includes and $excludes settings.
     *
     * The results may include basic field names (columns from the 'user' database table) and,
     * unless turned off, custom profile field names in the format 'profile_field_myfield'.
     *
     * You should not rely on the order of fields, with one exception: if there is an id field
     * it will be returned first. This is in case it is used with get_records calls.
     *
     * The $limitpurposes parameter is useful if you want to get a different set of fields than the
     * purposes in the constructor. For example, if you want to get SQL for identity + user picture
     * fields, but you then want to only get the identity fields as a list. (You can only specify
     * purposes that were also passed to the constructor i.e. it can only be used to restrict the
     * list, not add to it.)
     *
     * @param array $limitpurposes If specified, gets fields only for these purposes
     * @return string[] Array of required fields
     * @throws \coding_exception If any unknown purpose is listed
     */
    public function get_required_fields(array $limitpurposes = []): array {
        // The first time this is called, actually work out the list. There is no way to 'un-cache'
        // it, but these objects are designed to be short-lived so it doesn't need one.
        if ($this->fields === null) {
            // Add all the fields as array keys so that there are no duplicates.
            $this->fields = [];
            if ($this->purposes[self::PURPOSE_IDENTITY]) {
                foreach (self::get_identity_fields($this->context, $this->allowcustom) as $field) {
                    $this->fields[$field] = [self::PURPOSE_IDENTITY => true];
                }
            }
            if ($this->purposes[self::PURPOSE_USERPIC]) {
                foreach (self::get_picture_fields() as $field) {
                    if (!array_key_exists($field, $this->fields)) {
                        $this->fields[$field] = [];
                    }
                    $this->fields[$field][self::PURPOSE_USERPIC] = true;
                }
            }
            if ($this->purposes[self::PURPOSE_NAME]) {
                foreach (self::get_name_fields() as $field) {
                    if (!array_key_exists($field, $this->fields)) {
                        $this->fields[$field] = [];
                    }
                    $this->fields[$field][self::PURPOSE_NAME] = true;
                }
            }
            foreach ($this->include as $field) {
                if ($this->allowcustom || !preg_match(self::PROFILE_FIELD_REGEX, $field)) {
                    if (!array_key_exists($field, $this->fields)) {
                        $this->fields[$field] = [];
                    }
                    $this->fields[$field][self::CUSTOM_INCLUDE] = true;
                }
            }
            foreach ($this->exclude as $field) {
                unset($this->fields[$field]);
            }

            // If the id field is included, make sure it's first in the list.
            if (array_key_exists('id', $this->fields)) {
                $newfields = ['id' => $this->fields['id']];
                foreach ($this->fields as $field => $purposes) {
                    if ($field !== 'id') {
                        $newfields[$field] = $purposes;
                    }
                }
                $this->fields = $newfields;
            }
        }

        if ($limitpurposes) {
            // Check the value was legitimate.
            foreach ($limitpurposes as $purpose) {
                if ($purpose != self::CUSTOM_INCLUDE && empty($this->purposes[$purpose])) {
                    throw new \coding_exception('$limitpurposes can only include purposes defined in object');
                }
            }

            // Filter the fields to include only those matching the purposes.
            $result = [];
            foreach ($this->fields as $key => $purposes) {
                foreach ($limitpurposes as $purpose) {
                    if (array_key_exists($purpose, $purposes)) {
                        $result[] = $key;
                        break;
                    }
                }
            }
            return $result;
        } else {
            return array_keys($this->fields);
        }
    }

    /**
     * Gets fields required for user pictures.
     *
     * The results include only basic field names (columns from the 'user' database table).
     *
     * @return string[] All fields required for user pictures
     */
    public static function get_picture_fields(): array {
        return ['id', 'picture', 'firstname', 'lastname', 'firstnamephonetic', 'lastnamephonetic',
                'middlename', 'alternatename', 'imagealt', 'email'];
    }

    /**
     * Gets fields required for user names.
     *
     * The results include only basic field names (columns from the 'user' database table).
     *
     * Fields are usually returned in a specific order, which the fullname() function depends on.
     * If you specify 'true' to the $strangeorder flag, then the firstname and lastname fields
     * are moved to the front; this is useful in a few places in existing code. New code should
     * avoid requiring a particular order.
     *
     * @param bool $differentorder In a few places, a different order of fields is required
     * @return string[] All fields used to display user names
     */
    public static function get_name_fields(bool $differentorder = false): array {
        $fields = ['firstnamephonetic', 'lastnamephonetic', 'middlename', 'alternatename',
                'firstname', 'lastname'];
        if ($differentorder) {
            return array_merge(array_slice($fields, -2), array_slice($fields, 0, -2));
        } else {
            return $fields;
        }
    }

    /**
     * Gets all fields required for user identity. These fields should be included in tables
     * showing lists of users (in addition to the user's name which is included as standard).
     *
     * The results include basic field names (columns from the 'user' database table) and, unless
     * turned off, custom profile field names in the format 'profile_field_myfield', note these
     * fields will always be returned lower cased to match how they are returned by the DML library.
     *
     * This function does all the required capability checks to see if the current user is allowed
     * to see them in the specified context. You can pass context null to get all the fields
     * without checking permissions.
     *
     * @param \context|null $context Context; if not supplied, all fields will be included without checks
     * @param bool $allowcustom If true, custom profile fields will be included
     * @return string[] Array of required fields
     * @throws \coding_exception
     */
    public static function get_identity_fields(?\context $context, bool $allowcustom = true): array {
        global $CFG;

        // Only users with permission get the extra fields.
        if ($context && !has_capability('moodle/site:viewuseridentity', $context)) {
            return [];
        }

        // Split showuseridentity on comma (filter needed in case the showuseridentity is empty).
        $extra = array_filter(explode(',', $CFG->showuseridentity));

        // If there are any custom fields, remove them if necessary (either if allowcustom is false,
        // or if the user doesn't have access to see them).
        foreach ($extra as $key => $field) {
            if (preg_match(self::PROFILE_FIELD_REGEX, $field, $matches)) {
                $allowed = false;
                if ($allowcustom) {
                    require_once($CFG->dirroot . '/user/profile/lib.php');

                    // Ensure the field exists (it may have been deleted since user identity was configured).
                    $field = profile_get_custom_field_data_by_shortname($matches[1], false);
                    if ($field !== null) {
                        $fieldinstance = profile_get_user_field($field->datatype, $field->id, 0, $field);
                        $allowed = $fieldinstance->is_visible($context);
                    }
                }
                if (!$allowed) {
                    unset($extra[$key]);
                }
            }
        }

        // For standard user fields, access is controlled by the hiddenuserfields option and
        // some different capabilities. Check and remove these if the user can't access them.
        $hiddenfields = array_filter(explode(',', $CFG->hiddenuserfields));
        $hiddenidentifiers = array_intersect($extra, $hiddenfields);

        if ($hiddenidentifiers) {
            if (!$context) {
                $canviewhiddenuserfields = true;
            } else if ($context->get_course_context(false)) {
                // We are somewhere inside a course.
                $canviewhiddenuserfields = has_capability('moodle/course:viewhiddenuserfields', $context);
            } else {
                // We are not inside a course.
                $canviewhiddenuserfields = has_capability('moodle/user:viewhiddendetails', $context);
            }

            if (!$canviewhiddenuserfields) {
                // Remove hidden identifiers from the list.
                $extra = array_diff($extra, $hiddenidentifiers);
            }
        }

        // Re-index the entries and return.
        $extra = array_values($extra);
        return array_map([core_text::class, 'strtolower'], $extra);
    }

    /**
     * Gets SQL that can be used in a query to get the necessary fields.
     *
     * The result of this function is an object with fields 'selects', 'joins', 'params', and
     * 'mappings'.
     *
     * If not empty, the list of selects will begin with a comma and the list of joins will begin
     * and end with a space. You can include the result in your existing query like this:
     *
     * SELECT (your existing fields)
     *        $selects
     *   FROM {user} u
     *   JOIN (your existing joins)
     *        $joins
     *
     * When there are no custom fields then the 'joins' result will always be an empty string, and
     * 'params' will be an empty array.
     *
     * The $fieldmappings value is often not needed. It is an associative array from each field
     * name to an SQL expression for the value of that field, e.g.:
     *   'profile_field_frog' => 'uf1d_3.data'
     *   'city' => 'u.city'
     * This is helpful if you want to use the profile fields in a WHERE clause, becuase you can't
     * refer to the aliases used in the SELECT list there.
     *
     * The leading comma is included because this makes it work in the pattern above even if there
     * are no fields from the get_sql() data (which can happen if doing identity fields and none
     * are selected). If you want the result without a leading comma, set $leadingcomma to false.
     *
     * If the 'id' field is included then it will always be first in the list. Otherwise, you
     * should not rely on the field order.
     *
     * For identity fields, the function does all the required capability checks to see if the
     * current user is allowed to see them in the specified context. You can pass context null
     * to get all the fields without checking permissions.
     *
     * If your code for any reason cannot cope with custom fields then you can turn them off.
     *
     * You can have either named or ? params. If you use named params, they are of the form
     * uf1s_2; the first number increments in each call using a static variable in this class and
     * the second number refers to the field being queried. A similar pattern is used to make
     * join aliases unique.
     *
     * If your query refers to the user table by an alias e.g. 'u' then specify this in the $alias
     * parameter; otherwise it will use {user} (if there are any joins for custom profile fields)
     * or simply refer to the field by name only (if there aren't).
     *
     * If you need to use a prefix on the field names (for example in case they might coincide with
     * existing result columns from your query, or if you want a convenient way to split out all
     * the user data into a separate object) then you can specify one here. For example, if you
     * include name fields and the prefix is 'u_' then the results will include 'u_firstname'.
     *
     * If you don't want to prefix all the field names but only change the id field name, use
     * the $renameid parameter. (When you use this parameter, it takes precedence over any prefix;
     * the id field will not be prefixed, while all others will.)
     *
     * @param string $alias Optional (but recommended) alias for user table in query, e.g. 'u'
     * @param bool $namedparams If true, uses named :parameters instead of indexed ? parameters
     * @param string $prefix Optional prefix for all field names in result, e.g. 'u_'
     * @param string $renameid Renames the 'id' field if specified, e.g. 'userid'
     * @param bool $leadingcomma If true the 'selects' list will start with a comma
     * @return \stdClass Object with necessary SQL components
     */
    public function get_sql(string $alias = '', bool $namedparams = false, string $prefix = '',
            string $renameid = '', bool $leadingcomma = true): \stdClass {
        global $DB;

        $fields = $this->get_required_fields();

        $selects = '';
        $joins = '';
        $params = [];
        $mappings = [];

        $unique = self::$uniqueidentifier++;
        $fieldcount = 0;

        if ($alias) {
            $usertable = $alias . '.';
        } else {
            // If there is no alias, we still need to use {user} to identify the table when there
            // are joins with other tables. When there are no customfields then there are no joins
            // so we can refer to the fields by name alone.
            $gotcustomfields = false;
            foreach ($fields as $field) {
                if (preg_match(self::PROFILE_FIELD_REGEX, $field, $matches)) {
                    $gotcustomfields = true;
                    break;
                }
            }
            if ($gotcustomfields) {
                $usertable = '{user}.';
            } else {
                $usertable = '';
            }
        }

        foreach ($fields as $field) {
            if (preg_match(self::PROFILE_FIELD_REGEX, $field, $matches)) {
                // Custom profile field.
                $shortname = $matches[1];

                $fieldcount++;

                $fieldalias = 'uf' . $unique . 'f_' . $fieldcount;
                $dataalias = 'uf' . $unique . 'd_' . $fieldcount;
                if ($namedparams) {
                    $withoutcolon = 'uf' . $unique . 's' . $fieldcount;
                    $placeholder = ':' . $withoutcolon;
                    $params[$withoutcolon] = $shortname;
                } else {
                    $placeholder = '?';
                    $params[] = $shortname;
                }
                $joins .= " JOIN {user_info_field} $fieldalias ON " .
                                 $DB->sql_equal($fieldalias . '.shortname', $placeholder, false) . "
                       LEFT JOIN {user_info_data} $dataalias ON $dataalias.fieldid = $fieldalias.id
                                 AND $dataalias.userid = {$usertable}id";
                // For Oracle we need to convert the field into a usable format.
                $fieldsql = $DB->sql_compare_text($dataalias . '.data', 255);
                $selects .= ", $fieldsql AS $prefix$field";
                $mappings[$field] = $fieldsql;
            } else {
                // Standard user table field.
                $selects .= ", $usertable$field";
                if ($field === 'id' && $renameid && $renameid !== 'id') {
                    $selects .= " AS $renameid";
                } else if ($prefix) {
                    $selects .= " AS $prefix$field";
                }
                $mappings[$field] = "$usertable$field";
            }
        }

        // Add a space to the end of the joins list; this means it can be appended directly into
        // any existing query without worrying about whether the developer has remembered to add
        // whitespace after it.
        if ($joins) {
            $joins .= ' ';
        }

        // Optionally remove the leading comma.
        if (!$leadingcomma) {
            $selects = ltrim($selects, ' ,');
        }

        return (object)['selects' => $selects, 'joins' => $joins, 'params' => $params,
                'mappings' => $mappings];
    }

    /**
     * Similar to {@see \moodle_database::sql_fullname} except it returns all user name fields as defined by site config, in a
     * single select statement suitable for inclusion in a query/filter for a users fullname, e.g.
     *
     * [$select, $params] = fields::get_sql_fullname('u');
     * $users = $DB->get_records_sql_menu("SELECT u.id, {$select} FROM {user} u", $params);
     *
     * @param string|null $tablealias User table alias, if set elsewhere in the query, null if not required
     * @param bool $override If true then the alternativefullnameformat format rather than fullnamedisplay format will be used
     * @return array SQL select snippet and parameters
     */
    public static function get_sql_fullname(?string $tablealias = 'u', bool $override = false): array {
        global $DB;

        $unique = self::$uniqueidentifier++;

        $namefields = self::get_name_fields();

        // Create a dummy user object containing all name fields.
        $dummyuser = (object) array_combine($namefields, $namefields);
        $dummyfullname = fullname($dummyuser, $override);

        // Extract any name fields from the fullname format in the order that they appear.
        $matchednames = array_values(order_in_string($namefields, $dummyfullname));
        $namelookup = $namepattern = $elements = $params = [];

        foreach ($namefields as $index => $namefield) {
            $namefieldwithalias = $tablealias ? "{$tablealias}.{$namefield}" : $namefield;

            // Coalesce the name fields to ensure we don't return null.
            $emptyparam = "uf{$unique}ep_{$index}";
            $namelookup[$namefield] = "COALESCE({$namefieldwithalias}, :{$emptyparam})";
            $params[$emptyparam] = '';

            $namepattern[] = '\b' . preg_quote($namefield) . '\b';
        }

        // Grab any content between the name fields, inserting them after each name field.
        $chunks = preg_split('/(' . implode('|', $namepattern) . ')/', $dummyfullname);
        foreach ($chunks as $index => $chunk) {
            if ($index > 0) {
                $elements[] = $namelookup[$matchednames[$index - 1]];
            }

            if (core_text::strlen($chunk) > 0) {
                // If content is just whitespace, add to elements directly (also Oracle doesn't support passing ' ' as param).
                if (preg_match('/^\s+$/', $chunk)) {
                    $elements[] = "'$chunk'";
                } else {
                    $elementparam = "uf{$unique}fp_{$index}";
                    $elements[] = ":{$elementparam}";
                    $params[$elementparam] = $chunk;
                }
            }
        }

        return [$DB->sql_concat(...$elements), $params];
    }

    /**
     * Gets the display name of a given user field.
     *
     * Supports field names from the 'user' database table, and custom profile fields supplied in
     * the format 'profile_field_xx'.
     *
     * @param string $field Field name in database
     * @return string Field name for display to user
     * @throws \coding_exception
     */
    public static function get_display_name(string $field): string {
        global $CFG;

        // Custom fields have special handling.
        if (preg_match(self::PROFILE_FIELD_REGEX, $field, $matches)) {
            require_once($CFG->dirroot . '/user/profile/lib.php');
            $fieldinfo = profile_get_custom_field_data_by_shortname($matches[1], false);
            // Use format_string so it can be translated with multilang filter if necessary.
            return $fieldinfo ? format_string($fieldinfo->name) : $field;
        }

        // Some fields have language strings which are not the same as field name.
        switch ($field) {
            case 'picture' : {
                return get_string('pictureofuser');
            }
        }
        // Otherwise just use the same lang string.
        return get_string($field);
    }

    /**
     * Resets the unique identifier used to ensure that multiple SQL fragments generated in the
     * same request will have different identifiers for parameters and table aliases.
     *
     * This is intended only for use in unit testing.
     */
    public static function reset_unique_identifier() {
        self::$uniqueidentifier = 1;
    }

    /**
     * Checks if a field name looks like a custom profile field i.e. it begins with profile_field_
     * (does not check if that profile field actually exists).
     *
     * @param string $fieldname Field name
     * @return string Empty string if not a profile field, or profile field name (without profile_field_)
     */
    public static function match_custom_field(string $fieldname): string {
        if (preg_match(self::PROFILE_FIELD_REGEX, $fieldname, $matches)) {
            return $matches[1];
        } else {
            return '';
        }
    }
}

Youez - 2016 - github.com/yon3zu
LinuXploit