usermanager.lib.php 190 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400
  1. <?php
  2. /* For licensing terms, see /license.txt */
  3. /**
  4. * This library provides functions for user management.
  5. * Include/require it in your code to use its functionality.
  6. * @package chamilo.library
  7. * @author Julio Montoya <gugli100@gmail.com> Social network groups added 2009/12
  8. */
  9. /**
  10. * Code
  11. */
  12. /**
  13. * Class
  14. * @package chamilo.include.user
  15. */
  16. class UserManager
  17. {
  18. // Constants for user extra field types.
  19. const USER_FIELD_TYPE_TEXT = 1;
  20. const USER_FIELD_TYPE_TEXTAREA = 2;
  21. const USER_FIELD_TYPE_RADIO = 3;
  22. const USER_FIELD_TYPE_SELECT = 4;
  23. const USER_FIELD_TYPE_SELECT_MULTIPLE = 5;
  24. const USER_FIELD_TYPE_DATE = 6;
  25. const USER_FIELD_TYPE_DATETIME = 7;
  26. const USER_FIELD_TYPE_DOUBLE_SELECT = 8;
  27. const USER_FIELD_TYPE_DIVIDER = 9;
  28. const USER_FIELD_TYPE_TAG = 10;
  29. const USER_FIELD_TYPE_TIMEZONE = 11;
  30. const USER_FIELD_TYPE_SOCIAL_PROFILE = 12;
  31. /**
  32. * The default constructor only instanciates an empty user object
  33. */
  34. public function __construct()
  35. {
  36. }
  37. /**
  38. * Creates a new user for the platform
  39. * @author Hugues Peeters <peeters@ipm.ucl.ac.be>,
  40. * @author Roan Embrechts <roan_embrechts@yahoo.com>
  41. * @param string Firstname
  42. * @param string Lastname
  43. * @param int Status (1 for course tutor, 5 for student, 6 for anonymous)
  44. * @param string e-mail address
  45. * @param string Login
  46. * @param string Password
  47. * @param string Any official code (optional)
  48. * @param string User language (optional)
  49. * @param string Phone number (optional)
  50. * @param string Picture URI (optional)
  51. * @param string Authentication source (optional, defaults to 'platform', dependind on constant)
  52. * @param string Account expiration date (optional, defaults to '0000-00-00 00:00:00')
  53. * @param int Whether the account is enabled or disabled by default
  54. * @param int The department of HR in which the user is registered (optional, defaults to 0)
  55. * @param array Extra fields
  56. * @param string Encrypt method used if password is given encrypted. Set to an empty string by default
  57. * @return mixed new user id - if the new user creation succeeds, false otherwise
  58. * @desc The function tries to retrieve $_user['user_id'] from the global space. If it exists, $_user['user_id'] is the creator id. If a problem arises, it stores the error message in global $api_failureList
  59. * @assert ('Sam','Gamegie',5,'sam@example.com','jo','jo') > 1
  60. * @assert ('Pippin','Took',null,null,'jo','jo') === false
  61. */
  62. public static function create_user(
  63. $firstName,
  64. $lastName,
  65. $status,
  66. $email,
  67. $loginName,
  68. $password,
  69. $official_code = '',
  70. $language = '',
  71. $phone = '',
  72. $picture_uri = '',
  73. $auth_source = PLATFORM_AUTH_SOURCE,
  74. $expiration_date = '0000-00-00 00:00:00',
  75. $active = 1,
  76. $hr_dept_id = 0,
  77. $extra = null,
  78. $encrypt_method = '',
  79. $send_mail = false
  80. ) {
  81. global $_user, $_configuration;
  82. $original_password = $password;
  83. $access_url_id = 1;
  84. if (api_get_multiple_access_url()) {
  85. $access_url_id = api_get_current_access_url_id();
  86. }
  87. if (is_array($_configuration[$access_url_id]) &&
  88. isset($_configuration[$access_url_id]['hosting_limit_users']) &&
  89. $_configuration[$access_url_id]['hosting_limit_users'] > 0) {
  90. $num = self::get_number_of_users();
  91. if ($num >= $_configuration[$access_url_id]['hosting_limit_users']) {
  92. return api_set_failure('portal users limit reached');
  93. }
  94. }
  95. if ($status === 1 &&
  96. is_array($_configuration[$access_url_id]) &&
  97. isset($_configuration[$access_url_id]['hosting_limit_teachers']) &&
  98. $_configuration[$access_url_id]['hosting_limit_teachers'] > 0
  99. ) {
  100. $num = self::get_number_of_users(1);
  101. if ($num >= $_configuration[$access_url_id]['hosting_limit_teachers']) {
  102. return api_set_failure('portal teachers limit reached');
  103. }
  104. }
  105. $firstName = Security::remove_XSS($firstName);
  106. $lastName = Security::remove_XSS($lastName);
  107. $loginName = Security::remove_XSS($loginName);
  108. $phone = Security::remove_XSS($phone);
  109. // database table definition
  110. $table_user = Database::get_main_table(TABLE_MAIN_USER);
  111. //Checking the user language
  112. $languages = api_get_languages();
  113. $language = strtolower($language);
  114. if (!in_array($language, $languages['folder'])) {
  115. $language = api_get_setting('platformLanguage');
  116. }
  117. if ($_user['user_id']) {
  118. $creator_id = intval($_user['user_id']);
  119. } else {
  120. $creator_id = '';
  121. }
  122. // First check wether the login already exists
  123. if (!self::is_username_available($loginName)) {
  124. return api_set_failure('login-pass already taken');
  125. }
  126. //$password = "PLACEHOLDER";
  127. if (empty($encrypt_method)) {
  128. $password = api_get_encrypted_password($password);
  129. } else {
  130. if ($_configuration['password_encryption'] === $encrypt_method) {
  131. if ($encrypt_method == 'md5' && !preg_match('/^[A-Fa-f0-9]{32}$/', $password)) {
  132. return api_set_failure('encrypt_method invalid');
  133. } else if ($encrypt_method == 'sha1' && !preg_match('/^[A-Fa-f0-9]{40}$/', $password)) {
  134. return api_set_failure('encrypt_method invalid');
  135. }
  136. } else {
  137. return api_set_failure('encrypt_method invalid');
  138. }
  139. }
  140. //@todo replace this date with the api_get_utc_date function big problem with users that are already registered
  141. $current_date = date('Y-m-d H:i:s', time());
  142. $sql = "INSERT INTO $table_user
  143. SET lastname = '".Database::escape_string(trim($lastName))."',
  144. firstname = '".Database::escape_string(trim($firstName))."',
  145. username = '".Database::escape_string(trim($loginName))."',
  146. status = '".Database::escape_string($status)."',
  147. password = '".Database::escape_string($password)."',
  148. email = '".Database::escape_string($email)."',
  149. official_code = '".Database::escape_string($official_code)."',
  150. picture_uri = '".Database::escape_string($picture_uri)."',
  151. creator_id = '".Database::escape_string($creator_id)."',
  152. auth_source = '".Database::escape_string($auth_source)."',
  153. phone = '".Database::escape_string($phone)."',
  154. language = '".Database::escape_string($language)."',
  155. registration_date = '".$current_date."',
  156. expiration_date = '".Database::escape_string($expiration_date)."',
  157. hr_dept_id = '".Database::escape_string($hr_dept_id)."',
  158. active = '".Database::escape_string($active)."'";
  159. $result = Database::query($sql);
  160. if ($result) {
  161. //echo "id returned";
  162. $return = Database::insert_id();
  163. if (api_get_multiple_access_url()) {
  164. UrlManager::add_user_to_url($return, api_get_current_access_url_id());
  165. } else {
  166. //we are adding by default the access_url_user table with access_url_id = 1
  167. UrlManager::add_user_to_url($return, 1);
  168. }
  169. if (!empty($email) && $send_mail) {
  170. $recipient_name = api_get_person_name($firstName, $lastName, null, PERSON_NAME_EMAIL_ADDRESS);
  171. $emailsubject = '['.api_get_setting('siteName').'] '.get_lang('YourReg').' '.api_get_setting('siteName');
  172. $sender_name = api_get_person_name(api_get_setting('administratorName'), api_get_setting('administratorSurname'), null, PERSON_NAME_EMAIL_ADDRESS);
  173. $email_admin = api_get_setting('emailAdministrator');
  174. if (api_is_multiple_url_enabled()) {
  175. $access_url_id = api_get_current_access_url_id();
  176. if ($access_url_id != -1) {
  177. $url = api_get_access_url($access_url_id);
  178. $emailbody = get_lang('Dear')." ".stripslashes(api_get_person_name($firstName, $lastName)).",\n\n".get_lang('YouAreReg')." ".api_get_setting('siteName')." ".get_lang('WithTheFollowingSettings')."\n\n".get_lang('Username')." : ".$loginName."\n".get_lang('Pass')." : ".stripslashes($original_password)."\n\n".get_lang('Address')." ".api_get_setting('siteName')." ".get_lang('Is')." : ".$url['url']."\n\n".get_lang('Problem')."\n\n".get_lang('Formula').",\n\n".api_get_person_name(api_get_setting('administratorName'), api_get_setting('administratorSurname'))."\n".get_lang('Manager')." ".api_get_setting('siteName')."\nT. ".api_get_setting('administratorTelephone')."\n".get_lang('Email')." : ".api_get_setting('emailAdministrator');
  179. }
  180. } else {
  181. $emailbody = get_lang('Dear')." ".stripslashes(api_get_person_name($firstName, $lastName)).",\n\n".get_lang('YouAreReg')." ".api_get_setting('siteName')." ".get_lang('WithTheFollowingSettings')."\n\n".get_lang('Username')." : ".$loginName."\n".get_lang('Pass')." : ".stripslashes($original_password)."\n\n".get_lang('Address')." ".api_get_setting('siteName')." ".get_lang('Is')." : ".$_configuration['root_web']."\n\n".get_lang('Problem')."\n\n".get_lang('Formula').",\n\n".api_get_person_name(api_get_setting('administratorName'), api_get_setting('administratorSurname'))."\n".get_lang('Manager')." ".api_get_setting('siteName')."\nT. ".api_get_setting('administratorTelephone')."\n".get_lang('Email')." : ".api_get_setting('emailAdministrator');
  182. }
  183. /* MANAGE EVENT WITH MAIL */
  184. if (EventsMail::check_if_using_class('user_registration')) {
  185. $values["about_user"] = $return;
  186. $values["password"] = $original_password;
  187. $values["send_to"] = array($return);
  188. $values["prior_lang"] = null;
  189. EventsDispatcher::events('user_registration', $values);
  190. } else {
  191. api_mail_html($recipient_name, $email, $emailsubject, $emailbody, $sender_name, $email_admin);
  192. }
  193. /* ENDS MANAGE EVENT WITH MAIL */
  194. }
  195. event_system(LOG_USER_CREATE, LOG_USER_ID, $return);
  196. } else {
  197. return api_set_failure('error inserting in Database');
  198. }
  199. if (is_array($extra) && count($extra) > 0) {
  200. $res = true;
  201. foreach ($extra as $fname => $fvalue) {
  202. $res = $res && self::update_extra_field_value($return, $fname, $fvalue);
  203. }
  204. }
  205. self::update_extra_field_value($return, 'already_logged_in', 'false');
  206. return $return;
  207. }
  208. /**
  209. * Can user be deleted? This function checks whether there's a course
  210. * in which the given user is the
  211. * only course administrator. If that is the case, the user can't be
  212. * deleted because the course would remain without a course admin.
  213. * @param int $user_id The user id
  214. * @return boolean true if user can be deleted
  215. * @assert (null) === false
  216. * @assert (-1) === false
  217. * @assert ('abc') === false
  218. */
  219. public static function can_delete_user($user_id)
  220. {
  221. global $_configuration;
  222. if (isset($_configuration['deny_delete_users']) &&
  223. $_configuration['deny_delete_users'] == true
  224. ) {
  225. return false;
  226. }
  227. $table_course_user = Database :: get_main_table(TABLE_MAIN_COURSE_USER);
  228. if ($user_id != strval(intval($user_id)))
  229. return false;
  230. if ($user_id === false)
  231. return false;
  232. $sql = "SELECT * FROM $table_course_user
  233. WHERE status = '1' AND user_id = '".$user_id."'";
  234. $res = Database::query($sql);
  235. while ($course = Database::fetch_object($res)) {
  236. $sql = "SELECT user_id FROM $table_course_user
  237. WHERE status='1' AND course_code ='".Database::escape_string($course->course_code)."'";
  238. $res2 = Database::query($sql);
  239. if (Database::num_rows($res2) == 1) {
  240. return false;
  241. }
  242. }
  243. return true;
  244. }
  245. /**
  246. * Delete a user from the platform, and all its belongings. This is a
  247. * very dangerous function that should only be accessible by
  248. * super-admins. Other roles should only be able to disable a user,
  249. * which removes access to the platform but doesn't delete anything.
  250. * @param int The ID of th user to be deleted
  251. * @return boolean true if user is successfully deleted, false otherwise
  252. * @assert (null) === false
  253. * @assert ('abc') === false
  254. */
  255. public static function delete_user($user_id)
  256. {
  257. if ($user_id != strval(intval($user_id))) {
  258. return false;
  259. }
  260. if ($user_id === false) {
  261. return false;
  262. }
  263. if (!self::can_delete_user($user_id)) {
  264. return false;
  265. }
  266. $table_user = Database :: get_main_table(TABLE_MAIN_USER);
  267. $usergroup_rel_user = Database :: get_main_table(TABLE_USERGROUP_REL_USER);
  268. $table_course_user = Database :: get_main_table(TABLE_MAIN_COURSE_USER);
  269. $table_course = Database :: get_main_table(TABLE_MAIN_COURSE);
  270. $table_session = Database :: get_main_table(TABLE_MAIN_SESSION);
  271. $table_admin = Database :: get_main_table(TABLE_MAIN_ADMIN);
  272. $table_session_user = Database :: get_main_table(TABLE_MAIN_SESSION_USER);
  273. $table_session_course_user = Database :: get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
  274. $table_group = Database :: get_course_table(TABLE_GROUP_USER);
  275. $table_work = Database :: get_course_table(TABLE_STUDENT_PUBLICATION);
  276. // Unsubscribe the user from all groups in all his courses
  277. $sql = "SELECT c.id FROM $table_course c, $table_course_user cu
  278. WHERE
  279. cu.user_id = '".$user_id."' AND
  280. relation_type<>".COURSE_RELATION_TYPE_RRHH." AND
  281. c.code = cu.course_code";
  282. $res = Database::query($sql);
  283. while ($course = Database::fetch_object($res)) {
  284. $sql = "DELETE FROM $table_group
  285. WHERE c_id = {$course->id} AND user_id = $user_id";
  286. Database::query($sql);
  287. }
  288. // Unsubscribe user from all classes
  289. //Classes are not longer supported
  290. /* $sql = "DELETE FROM $table_class_user WHERE user_id = '".$user_id."'";
  291. Database::query($sql); */
  292. // Unsubscribe user from usergroup_rel_user
  293. $sql = "DELETE FROM $usergroup_rel_user WHERE user_id = '".$user_id."'";
  294. Database::query($sql);
  295. // Unsubscribe user from all courses
  296. $sql = "DELETE FROM $table_course_user WHERE user_id = '".$user_id."'";
  297. Database::query($sql);
  298. // Unsubscribe user from all courses in sessions
  299. $sql = "DELETE FROM $table_session_course_user WHERE id_user = '".$user_id."'";
  300. Database::query($sql);
  301. // If the user was added as a id_coach then set the current admin as coach see BT#
  302. $currentUserId = api_get_user_id();
  303. $sql = "UPDATE $table_session SET id_coach = $currentUserId WHERE id_coach = '".$user_id."'";
  304. Database::query($sql);
  305. $sql = "UPDATE $table_session SET id_coach = $currentUserId WHERE session_admin_id = '".$user_id."'";
  306. Database::query($sql);
  307. // Unsubscribe user from all sessions
  308. $sql = "DELETE FROM $table_session_user WHERE id_user = '".$user_id."'";
  309. Database::query($sql);
  310. // Delete user picture
  311. /* TODO: Logic about api_get_setting('split_users_upload_directory') == 'true'
  312. a user has 4 differnt sized photos to be deleted. */
  313. $user_info = api_get_user_info($user_id);
  314. if (strlen($user_info['picture_uri']) > 0) {
  315. $img_path = api_get_path(SYS_CODE_PATH).'upload/users/'.$user_id.'/'.$user_info['picture_uri'];
  316. if (file_exists($img_path))
  317. unlink($img_path);
  318. }
  319. // Delete the personal course categories
  320. $course_cat_table = Database::get_user_personal_table(TABLE_USER_COURSE_CATEGORY);
  321. $sql = "DELETE FROM $course_cat_table WHERE user_id = '".$user_id."'";
  322. Database::query($sql);
  323. // Delete user from database
  324. $sql = "DELETE FROM $table_user WHERE user_id = '".$user_id."'";
  325. Database::query($sql);
  326. // Delete user from the admin table
  327. $sql = "DELETE FROM $table_admin WHERE user_id = '".$user_id."'";
  328. Database::query($sql);
  329. // Delete the personal agenda-items from this user
  330. $agenda_table = Database :: get_user_personal_table(TABLE_PERSONAL_AGENDA);
  331. $sql = "DELETE FROM $agenda_table WHERE user = '".$user_id."'";
  332. Database::query($sql);
  333. $gradebook_results_table = Database :: get_main_table(TABLE_MAIN_GRADEBOOK_RESULT);
  334. $sql = 'DELETE FROM '.$gradebook_results_table.' WHERE user_id = '.$user_id;
  335. Database::query($sql);
  336. $t_ufv = Database::get_main_table(TABLE_MAIN_USER_FIELD_VALUES);
  337. $sqlv = "DELETE FROM $t_ufv WHERE user_id = $user_id";
  338. Database::query($sqlv);
  339. require_once api_get_path(LIBRARY_PATH).'urlmanager.lib.php';
  340. if (api_get_multiple_access_url()) {
  341. $url_id = api_get_current_access_url_id();
  342. UrlManager::delete_url_rel_user($user_id, $url_id);
  343. } else {
  344. //we delete the user from the url_id =1
  345. UrlManager::delete_url_rel_user($user_id, 1);
  346. }
  347. if (api_get_setting('allow_social_tool') == 'true') {
  348. require_once api_get_path(LIBRARY_PATH).'group_portal_manager.lib.php';
  349. //Delete user from portal groups
  350. $group_list = GroupPortalManager::get_groups_by_user($user_id);
  351. if (!empty($group_list)) {
  352. foreach ($group_list as $group_id => $data) {
  353. GroupPortalManager::delete_user_rel_group($user_id, $group_id);
  354. }
  355. }
  356. // Delete user from friend lists
  357. SocialManager::remove_user_rel_user($user_id, true);
  358. }
  359. // Removing survey invitation
  360. survey_manager::delete_all_survey_invitations_by_user($user_id);
  361. // Delete students works
  362. $sql = "DELETE FROM $table_work WHERE user_id = $user_id AND c_id <> 0";
  363. Database::query($sql);
  364. // Add event to system log
  365. $user_id_manager = api_get_user_id();
  366. event_system(LOG_USER_DELETE, LOG_USER_ID, $user_id, api_get_utc_datetime(), $user_id_manager, null, $user_info);
  367. event_system(LOG_USER_DELETE, LOG_USER_OBJECT, $user_info, api_get_utc_datetime(), $user_id_manager, null, $user_info);
  368. return true;
  369. }
  370. /**
  371. * Deletes users completely. Can be called either as:
  372. * - UserManager :: delete_users(1, 2, 3); or
  373. * - UserManager :: delete_users(array(1, 2, 3));
  374. * @param array|int $ids
  375. * @return boolean True if at least one user was successfuly deleted. False otherwise.
  376. * @author Laurent Opprecht
  377. * @uses UserManager::delete_user() to actually delete each user
  378. * @assert (null) === false
  379. * @assert (-1) === false
  380. * @assert (array(-1)) === false
  381. */
  382. static function delete_users($ids = array())
  383. {
  384. $result = false;
  385. $ids = is_array($ids) ? $ids : func_get_args();
  386. if (!is_array($ids) or count($ids) == 0) { return false; }
  387. $ids = array_map('intval', $ids);
  388. foreach ($ids as $id) {
  389. if (empty($id) or $id < 1) { continue; }
  390. $deleted = self::delete_user($id);
  391. $result = $deleted || $result;
  392. }
  393. return $result;
  394. }
  395. /**
  396. * Disable users. Can be called either as:
  397. * - UserManager :: deactivate_users(1, 2, 3);
  398. * - UserManager :: deactivate_users(array(1, 2, 3));
  399. * @param array|int $ids
  400. * @return boolean
  401. * @author Laurent Opprecht
  402. * @assert (null) === false
  403. * @assert (array(-1)) === false
  404. */
  405. static function deactivate_users($ids = array())
  406. {
  407. if (empty($ids)) {
  408. return false;
  409. }
  410. $table_user = Database :: get_main_table(TABLE_MAIN_USER);
  411. $ids = is_array($ids) ? $ids : func_get_args();
  412. $ids = array_map('intval', $ids);
  413. $ids = implode(',', $ids);
  414. $sql = "UPDATE $table_user SET active = 0 WHERE user_id IN ($ids)";
  415. $r = Database::query($sql);
  416. if ($r !== false) {
  417. event_system(LOG_USER_DISABLE,LOG_USER_ID,$ids);
  418. }
  419. return $r;
  420. }
  421. /**
  422. * Enable users. Can be called either as:
  423. * - UserManager :: activate_users(1, 2, 3);
  424. * - UserManager :: activate_users(array(1, 2, 3));
  425. * @param array|int IDs of the users to enable
  426. * @return boolean
  427. * @author Laurent Opprecht
  428. * @assert (null) === false
  429. * @assert (array(-1)) === false
  430. */
  431. static function activate_users($ids = array())
  432. {
  433. if (empty($ids)) {
  434. return false;
  435. }
  436. $table_user = Database :: get_main_table(TABLE_MAIN_USER);
  437. $ids = is_array($ids) ? $ids : func_get_args();
  438. $ids = array_map('intval', $ids);
  439. $ids = implode(',', $ids);
  440. $sql = "UPDATE $table_user SET active = 1 WHERE user_id IN ($ids)";
  441. $r = Database::query($sql);
  442. if ($r !== false) {
  443. event_system(LOG_USER_ENABLE,LOG_USER_ID,$ids);
  444. }
  445. return $r;
  446. }
  447. /**
  448. * Update user information with new openid
  449. * @param int $user_id
  450. * @param string $openid
  451. * @return boolean true if the user information was updated
  452. * @assert (false,'') === false
  453. * @assert (-1,'') === false
  454. */
  455. public static function update_openid($user_id, $openid)
  456. {
  457. $table_user = Database :: get_main_table(TABLE_MAIN_USER);
  458. if ($user_id != strval(intval($user_id)))
  459. return false;
  460. if ($user_id === false)
  461. return false;
  462. $sql = "UPDATE $table_user SET
  463. openid='".Database::escape_string($openid)."'";
  464. $sql .= " WHERE user_id='$user_id'";
  465. return Database::query($sql);
  466. }
  467. /**
  468. * Update user information with all the parameters passed to this function
  469. * @param int The ID of the user to be updated
  470. * @param string The user's firstname
  471. * @param string The user's lastname
  472. * @param string The user's username (login)
  473. * @param string The user's password
  474. * @param string The authentication source (default: "platform")
  475. * @param string The user's e-mail address
  476. * @param int The user's status
  477. * @param string The user's official code (usually just an internal institutional code)
  478. * @param string The user's phone number
  479. * @param string The user's picture URL (internal to the Chamilo directory)
  480. * @param int The user ID of the person who registered this user (optional, defaults to null)
  481. * @param int The department of HR in which the user is registered (optional, defaults to 0)
  482. * @param array A series of additional fields to add to this user as extra fields (optional, defaults to null)
  483. * @return boolean true if the user information was updated
  484. * @assert (false, false, false, false, false, false, false, false, false, false, false, false, false) === false
  485. */
  486. public static function update_user(
  487. $user_id,
  488. $firstname,
  489. $lastname,
  490. $username,
  491. $password = null,
  492. $auth_source = null,
  493. $email,
  494. $status,
  495. $official_code,
  496. $phone,
  497. $picture_uri,
  498. $expiration_date,
  499. $active,
  500. $creator_id = null,
  501. $hr_dept_id = 0,
  502. $extra = null,
  503. $language = 'english',
  504. $encrypt_method = '',
  505. $send_email = false,
  506. $reset_password = 0
  507. ) {
  508. global $_configuration;
  509. $original_password = $password;
  510. if (empty($user_id)) { return false; }
  511. $user_info = api_get_user_info($user_id, false, true);
  512. if ($reset_password == 0) {
  513. $password = null;
  514. $auth_source = $user_info['auth_source'];
  515. } elseif ($reset_password == 1) {
  516. $original_password = $password = api_generate_password();
  517. $auth_source = PLATFORM_AUTH_SOURCE;
  518. } elseif ($reset_password == 2) {
  519. $password = $password;
  520. $auth_source = PLATFORM_AUTH_SOURCE;
  521. } elseif ($reset_password == 3) {
  522. $password = $password;
  523. $auth_source = $auth_source;
  524. }
  525. if ($user_id != strval(intval($user_id)))
  526. return false;
  527. if ($user_id === false)
  528. return false;
  529. $table_user = Database :: get_main_table(TABLE_MAIN_USER);
  530. //Checking the user language
  531. $languages = api_get_languages();
  532. if (!in_array($language, $languages['folder'])) {
  533. $language = api_get_setting('platformLanguage');
  534. }
  535. $change_active = 0;
  536. if ($user_info['active'] != $active) {
  537. $change_active = 1;
  538. }
  539. $sql = "UPDATE $table_user SET
  540. lastname='".Database::escape_string($lastname)."',
  541. firstname='".Database::escape_string($firstname)."',
  542. username='".Database::escape_string($username)."',
  543. language='".Database::escape_string($language)."',";
  544. if (!is_null($password)) {
  545. if ($encrypt_method == '') {
  546. $password = api_get_encrypted_password($password);
  547. } else {
  548. if ($_configuration['password_encryption'] === $encrypt_method) {
  549. if ($encrypt_method == 'md5' && !preg_match('/^[A-Fa-f0-9]{32}$/', $password)) {
  550. return api_set_failure('encrypt_method invalid');
  551. } else if ($encrypt_method == 'sha1' && !preg_match('/^[A-Fa-f0-9]{40}$/', $password)) {
  552. return api_set_failure('encrypt_method invalid');
  553. }
  554. } else {
  555. return api_set_failure('encrypt_method invalid');
  556. }
  557. }
  558. $sql .= " password='".Database::escape_string($password)."',";
  559. }
  560. if (!is_null($auth_source)) {
  561. $sql .= " auth_source='".Database::escape_string($auth_source)."',";
  562. }
  563. $sql .= "
  564. email='".Database::escape_string($email)."',
  565. status='".Database::escape_string($status)."',
  566. official_code='".Database::escape_string($official_code)."',
  567. phone='".Database::escape_string($phone)."',
  568. picture_uri='".Database::escape_string($picture_uri)."',
  569. expiration_date='".Database::escape_string($expiration_date)."',
  570. active='".Database::escape_string($active)."',
  571. hr_dept_id=".intval($hr_dept_id);
  572. if (!is_null($creator_id)) {
  573. $sql .= ", creator_id='".Database::escape_string($creator_id)."'";
  574. }
  575. $sql .= " WHERE user_id='$user_id'";
  576. $return = Database::query($sql);
  577. if ($change_active == 1 && $return) {
  578. if ($active == 1) {
  579. $event_title = LOG_USER_ENABLE;
  580. } else {
  581. $event_title = LOG_USER_DISABLE;
  582. }
  583. event_system($event_title, LOG_USER_ID, $user_id);
  584. }
  585. if (is_array($extra) && count($extra) > 0) {
  586. $res = true;
  587. foreach ($extra as $fname => $fvalue) {
  588. $res = $res && self::update_extra_field_value($user_id, $fname, $fvalue);
  589. }
  590. }
  591. if (!empty($email) && $send_email) {
  592. $recipient_name = api_get_person_name($firstname, $lastname, null, PERSON_NAME_EMAIL_ADDRESS);
  593. $emailsubject = '['.api_get_setting('siteName').'] '.get_lang('YourReg').' '.api_get_setting('siteName');
  594. $sender_name = api_get_person_name(api_get_setting('administratorName'), api_get_setting('administratorSurname'), null, PERSON_NAME_EMAIL_ADDRESS);
  595. $email_admin = api_get_setting('emailAdministrator');
  596. if (api_is_multiple_url_enabled()) {
  597. $access_url_id = api_get_current_access_url_id();
  598. if ($access_url_id != -1) {
  599. $url = api_get_access_url($access_url_id);
  600. $emailbody = get_lang('Dear')." ".stripslashes(api_get_person_name($firstname, $lastname)).",\n\n".get_lang('YouAreReg')." ".api_get_setting('siteName')." ".get_lang('WithTheFollowingSettings')."\n\n".get_lang('Username')." : ".$username.(($reset_password > 0) ? "\n".get_lang('Pass')." : ".stripslashes($original_password) : "")."\n\n".get_lang('Address')." ".api_get_setting('siteName')." ".get_lang('Is')." : ".$url['url']."\n\n".get_lang('Problem')."\n\n".get_lang('Formula').",\n\n".api_get_person_name(api_get_setting('administratorName'), api_get_setting('administratorSurname'))."\n".get_lang('Manager')." ".api_get_setting('siteName')."\nT. ".api_get_setting('administratorTelephone')."\n".get_lang('Email')." : ".api_get_setting('emailAdministrator');
  601. }
  602. } else {
  603. $emailbody = get_lang('Dear')." ".stripslashes(api_get_person_name($firstname, $lastname)).",\n\n".get_lang('YouAreReg')." ".api_get_setting('siteName')." ".get_lang('WithTheFollowingSettings')."\n\n".get_lang('Username')." : ".$username.(($reset_password > 0) ? "\n".get_lang('Pass')." : ".stripslashes($original_password) : "")."\n\n".get_lang('Address')." ".api_get_setting('siteName')." ".get_lang('Is')." : ".$_configuration['root_web']."\n\n".get_lang('Problem')."\n\n".get_lang('Formula').",\n\n".api_get_person_name(api_get_setting('administratorName'), api_get_setting('administratorSurname'))."\n".get_lang('Manager')." ".api_get_setting('siteName')."\nT. ".api_get_setting('administratorTelephone')."\n".get_lang('Email')." : ".api_get_setting('emailAdministrator');
  604. }
  605. @api_mail_html($recipient_name, $email, $emailsubject, $emailbody, $sender_name, $email_admin);
  606. }
  607. return $return;
  608. }
  609. /**
  610. * Disables or enables a user
  611. * @param int user_id
  612. * @param int Enable or disable
  613. * @return void
  614. * @assert (-1,0) === false
  615. * @assert (1,1) === true
  616. */
  617. private static function change_active_state($user_id, $active)
  618. {
  619. if (strval(intval($user_id)) != $user_id) {
  620. return false;
  621. }
  622. if ($user_id < 1) {
  623. return false;
  624. }
  625. $user_id = intval($user_id);
  626. $table_user = Database :: get_main_table(TABLE_MAIN_USER);
  627. $sql = "UPDATE $table_user SET active = '$active' WHERE user_id = '$user_id';";
  628. $r = Database::query($sql);
  629. $ev = LOG_USER_DISABLE;
  630. if ($active == 1) {
  631. $ev = LOG_USER_ENABLE;
  632. }
  633. if ($r !== false) {
  634. event_system($ev,LOG_USER_ID,$user_id);
  635. }
  636. return $r;
  637. }
  638. /**
  639. * Disables a user
  640. * @param int User id
  641. * @uses UserManager::change_active_state() to actually disable the user
  642. * @assert (0) === false
  643. */
  644. public static function disable($user_id)
  645. {
  646. self::change_active_state($user_id, 0);
  647. }
  648. /**
  649. * Enable a user
  650. * @param int User id
  651. * @uses UserManager::change_active_state() to actually disable the user
  652. * @assert (0) === false
  653. */
  654. public static function enable($user_id)
  655. {
  656. self::change_active_state($user_id, 1);
  657. }
  658. /**
  659. * Returns the user's id based on the original id and field name in
  660. * the extra fields. Returns 0 if no user was found. This function is
  661. * mostly useful in the context of a web services-based sinchronization
  662. * @param string Original user id
  663. * @param string Original field name
  664. * @return int User id
  665. * @assert ('0','---') === 0
  666. */
  667. public static function get_user_id_from_original_id($original_user_id_value, $original_user_id_name)
  668. {
  669. $t_uf = Database::get_main_table(TABLE_MAIN_USER_FIELD);
  670. $t_ufv = Database::get_main_table(TABLE_MAIN_USER_FIELD_VALUES);
  671. $sql = "SELECT user_id
  672. FROM $t_uf uf
  673. INNER JOIN $t_ufv ufv
  674. ON ufv.field_id=uf.id
  675. WHERE
  676. field_variable='$original_user_id_name' AND
  677. field_value='$original_user_id_value';";
  678. $res = Database::query($sql);
  679. $row = Database::fetch_object($res);
  680. if ($row) {
  681. return $row->user_id;
  682. } else {
  683. return 0;
  684. }
  685. }
  686. /**
  687. * Check if a username is available
  688. * @param string the wanted username
  689. * @return boolean true if the wanted username is available
  690. * @assert ('') === false
  691. * @assert ('xyzxyzxyz') === true
  692. */
  693. public static function is_username_available($username)
  694. {
  695. if (empty($username)) {
  696. return false;
  697. }
  698. $table_user = Database :: get_main_table(TABLE_MAIN_USER);
  699. $sql = "SELECT username FROM $table_user
  700. WHERE username = '".Database::escape_string($username)."'";
  701. $res = Database::query($sql);
  702. return Database::num_rows($res) == 0;
  703. }
  704. /**
  705. * Creates a username using person's names, i.e. creates jmontoya from Julio Montoya.
  706. * @param string $firstname The first name of the user.
  707. * @param string $lastname The last name of the user.
  708. * @param string $language (optional) The language in which comparison is to be made. If language is omitted, interface language is assumed then.
  709. * @param string $encoding (optional) The character encoding for the input names. If it is omitted, the platform character set will be used by default.
  710. * @return string Suggests a username that contains only ASCII-letters and digits, without check for uniqueness within the system.
  711. * @author Julio Montoya Armas
  712. * @author Ivan Tcholakov, 2009 - rework about internationalization.
  713. * @assert ('','') === false
  714. * @assert ('a','b') === 'ab'
  715. */
  716. public static function create_username($firstname, $lastname, $language = null, $encoding = null)
  717. {
  718. if (is_null($encoding)) {
  719. $encoding = api_get_system_encoding();
  720. }
  721. if (is_null($language)) {
  722. $language = api_get_interface_language();
  723. }
  724. $firstname = api_substr(preg_replace(USERNAME_PURIFIER, '', api_transliterate($firstname, '', $encoding)), 0, 1); // The first letter only.
  725. //Looking for a space in the lastname
  726. $pos = api_strpos($lastname, ' ');
  727. if ($pos !== false) {
  728. $lastname = api_substr($lastname, 0, $pos);
  729. }
  730. $lastname = preg_replace(USERNAME_PURIFIER, '', api_transliterate($lastname, '', $encoding));
  731. //$username = api_is_western_name_order(null, $language) ? $firstname.$lastname : $lastname.$firstname;
  732. $username = $firstname.$lastname;
  733. if (empty($username)) {
  734. $username = 'user';
  735. }
  736. return strtolower(substr($username, 0, USERNAME_MAX_LENGTH - 3));
  737. }
  738. /**
  739. * Creates a unique username, using:
  740. * 1. the first name and the last name of a user;
  741. * 2. an already created username but not checked for uniqueness yet.
  742. * @param string $firstname The first name of a given user. If the second parameter $lastname is NULL, then this
  743. * parameter is treated as username which is to be checked for uniqueness and to be modified when it is necessary.
  744. * @param string $lastname The last name of the user.
  745. * @param string $language (optional) The language in which comparison is to be made. If language is omitted, interface language is assumed then.
  746. * @param string $encoding (optional) The character encoding for the input names. If it is omitted, the platform character set will be used by default.
  747. * @return string Returns a username that contains only ASCII-letters and digits, and that is unique within the system.
  748. * Note: When the method is called several times with same parameters, its results look like the following sequence: ivan, ivan2, ivan3, ivan4, ...
  749. * @author Ivan Tcholakov, 2009
  750. */
  751. public static function create_unique_username($firstname, $lastname = null, $language = null, $encoding = null)
  752. {
  753. if (is_null($lastname)) {
  754. // In this case the actual input parameter $firstname should contain ASCII-letters and digits only.
  755. // For making this method tolerant of mistakes, let us transliterate and purify the suggested input username anyway.
  756. // So, instead of the sentence $username = $firstname; we place the following:
  757. $username = strtolower(preg_replace(USERNAME_PURIFIER, '', api_transliterate($firstname, '', $encoding)));
  758. } else {
  759. $username = self::create_username($firstname, $lastname, $language, $encoding);
  760. }
  761. if (!self::is_username_available($username)) {
  762. $i = 2;
  763. $temp_username = substr($username, 0, USERNAME_MAX_LENGTH - strlen((string) $i)).$i;
  764. while (!self::is_username_available($temp_username)) {
  765. $i++;
  766. $temp_username = substr($username, 0, USERNAME_MAX_LENGTH - strlen((string) $i)).$i;
  767. }
  768. $username = $temp_username;
  769. }
  770. return $username;
  771. }
  772. /**
  773. * Modifies a given username accordingly to the specification for valid characters and length.
  774. * @param $username string The input username.
  775. * @param bool $strict (optional) When this flag is TRUE, the result is guaranteed for full compliance, otherwise compliance may be partial. The default value is FALSE.
  776. * @param string $encoding (optional) The character encoding for the input names. If it is omitted, the platform character set will be used by default.
  777. * @return string The resulting purified username.
  778. */
  779. public static function purify_username($username, $strict = false, $encoding = null)
  780. {
  781. if ($strict) {
  782. // 1. Conversion of unacceptable letters (latinian letters with accents for example) into ASCII letters in order they not to be totally removed.
  783. // 2. Applying the strict purifier.
  784. // 3. Length limitation.
  785. $toreturn = api_get_setting('login_is_email') == 'true' ? substr(preg_replace(USERNAME_PURIFIER_MAIL, '', api_transliterate($username, '', $encoding)), 0, USERNAME_MAX_LENGTH) : substr(preg_replace(USERNAME_PURIFIER, '', api_transliterate($username, '', $encoding)), 0, USERNAME_MAX_LENGTH);
  786. return $toreturn;
  787. }
  788. // 1. Applying the shallow purifier.
  789. // 2. Length limitation.
  790. return substr(preg_replace(USERNAME_PURIFIER_SHALLOW, '', $username), 0, USERNAME_MAX_LENGTH);
  791. }
  792. /**
  793. * Checks whether the user id exists in the database
  794. *
  795. * @param int User id
  796. * @return bool True if user id was found, false otherwise
  797. */
  798. public static function is_user_id_valid($user_id)
  799. {
  800. $user_id = (int) $user_id;
  801. $table_user = Database :: get_main_table(TABLE_MAIN_USER);
  802. $sql = "SELECT user_id FROM $table_user WHERE user_id = '".$user_id."'";
  803. $res = Database::query($sql);
  804. $num_rows = Database::num_rows($res);
  805. if ($num_rows == 0) {
  806. return false;
  807. } else {
  808. return true;
  809. }
  810. }
  811. /**
  812. * Checks whether a given username matches to the specification strictly. The empty username is assumed here as invalid.
  813. * Mostly this function is to be used in the user interface built-in validation routines for providing feedback while usernames are enterd manually.
  814. * @param string $username The input username.
  815. * @param string $encoding (optional) The character encoding for the input names. If it is omitted, the platform character set will be used by default.
  816. * @return bool Returns TRUE if the username is valid, FALSE otherwise.
  817. */
  818. public static function is_username_valid($username, $encoding = null)
  819. {
  820. return !empty($username) && $username == self::purify_username($username, true);
  821. }
  822. /**
  823. * Checks whether a username is empty. If the username contains whitespace characters, such as spaces, tabulators, newlines, etc.,
  824. * it is assumed as empty too. This function is safe for validation unpurified data (during importing).
  825. * @param string $username The given username.
  826. * @return bool Returns TRUE if length of the username exceeds the limit, FALSE otherwise.
  827. */
  828. public static function is_username_empty($username)
  829. {
  830. return (strlen(self::purify_username($username, false)) == 0);
  831. }
  832. /**
  833. * Checks whether a username is too long or not.
  834. * @param string $username The given username, it should contain only ASCII-letters and digits.
  835. * @return bool Returns TRUE if length of the username exceeds the limit, FALSE otherwise.
  836. */
  837. public static function is_username_too_long($username)
  838. {
  839. return (strlen($username) > USERNAME_MAX_LENGTH);
  840. }
  841. /**
  842. * @param array $ids
  843. * @param null $active
  844. * @return array
  845. */
  846. public static function get_user_list_by_ids($ids = array(), $active = null)
  847. {
  848. if (empty($ids)) {
  849. return array();
  850. }
  851. $ids = is_array($ids) ? $ids : array($ids);
  852. $ids = array_map('intval', $ids);
  853. $ids = implode(',', $ids);
  854. $tbl_user = Database::get_main_table(TABLE_MAIN_USER);
  855. $sql = "SELECT * FROM $tbl_user WHERE user_id IN ($ids)";
  856. if (!is_null($active)) {
  857. $sql .= ' AND active='.($active ? '1' : '0');
  858. }
  859. $rs = Database::query($sql);
  860. $result = array();
  861. while ($row = Database::fetch_array($rs)) {
  862. $result[] = $row;
  863. }
  864. return $result;
  865. }
  866. /**
  867. * Get a list of users of which the given conditions match with an = 'cond'
  868. * @param array $conditions a list of condition (exemple : status=>STUDENT)
  869. * @param array $order_by a list of fields on which sort
  870. * @return array An array with all users of the platform.
  871. * @todo optional course code parameter, optional sorting parameters...
  872. */
  873. public static function get_user_list($conditions = array(), $order_by = array(), $limit_from = false, $limit_to = false)
  874. {
  875. $user_table = Database :: get_main_table(TABLE_MAIN_USER);
  876. $return_array = array();
  877. $sql_query = "SELECT * FROM $user_table";
  878. if (count($conditions) > 0) {
  879. $sql_query .= ' WHERE ';
  880. foreach ($conditions as $field => $value) {
  881. $field = Database::escape_string($field);
  882. $value = Database::escape_string($value);
  883. $sql_query .= "$field = '$value'";
  884. }
  885. }
  886. if (count($order_by) > 0) {
  887. $sql_query .= ' ORDER BY '.Database::escape_string(implode(',', $order_by));
  888. }
  889. if (is_numeric($limit_from) && is_numeric($limit_from)) {
  890. $limit_from = intval($limit_from);
  891. $limit_to = intval($limit_to);
  892. $sql_query .= " LIMIT $limit_from, $limit_to";
  893. }
  894. $sql_result = Database::query($sql_query);
  895. while ($result = Database::fetch_array($sql_result)) {
  896. $return_array[] = $result;
  897. }
  898. return $return_array;
  899. }
  900. /**
  901. * Get a list of users of which the given conditions match with a LIKE '%cond%'
  902. * @param array $conditions a list of condition (exemple : status=>STUDENT)
  903. * @param array $order_by a list of fields on which sort
  904. * @return array An array with all users of the platform.
  905. * @todo optional course code parameter, optional sorting parameters...
  906. */
  907. public static function get_user_list_like($conditions = array(), $order_by = array(), $simple_like = false, $condition = 'AND')
  908. {
  909. $user_table = Database :: get_main_table(TABLE_MAIN_USER);
  910. $return_array = array();
  911. $sql_query = "SELECT * FROM $user_table";
  912. if (count($conditions) > 0) {
  913. $sql_query .= ' WHERE ';
  914. $temp_conditions = array();
  915. foreach ($conditions as $field => $value) {
  916. $field = Database::escape_string($field);
  917. $value = Database::escape_string($value);
  918. if ($simple_like) {
  919. $temp_conditions[] = $field." LIKE '$value%'";
  920. } else {
  921. $temp_conditions[] = $field.' LIKE \'%'.$value.'%\'';
  922. }
  923. }
  924. if (!empty($temp_conditions)) {
  925. $sql_query .= implode(' '.$condition.' ', $temp_conditions);
  926. }
  927. }
  928. if (count($order_by) > 0) {
  929. $sql_query .= ' ORDER BY '.Database::escape_string(implode(',', $order_by));
  930. }
  931. $sql_result = Database::query($sql_query);
  932. while ($result = Database::fetch_array($sql_result)) {
  933. $return_array[] = $result;
  934. }
  935. return $return_array;
  936. }
  937. /**
  938. * Get user information
  939. * @param string The username
  940. * @return array All user information as an associative array
  941. */
  942. public static function get_user_info($username)
  943. {
  944. $user_table = Database :: get_main_table(TABLE_MAIN_USER);
  945. $username = Database::escape_string($username);
  946. $sql = "SELECT * FROM $user_table WHERE username='".$username."'";
  947. $res = Database::query($sql);
  948. if (Database::num_rows($res) > 0) {
  949. return Database::fetch_array($res);
  950. }
  951. return false;
  952. }
  953. /**
  954. * Get user information
  955. * @param string The id
  956. * @param boolean Whether to return the user's extra fields (defaults to false)
  957. * @return array All user information as an associative array
  958. * @todo Use api_get_user_info() instead
  959. */
  960. public static function get_user_info_by_id($user_id, $user_fields = false)
  961. {
  962. $user_id = intval($user_id);
  963. $user_table = Database :: get_main_table(TABLE_MAIN_USER);
  964. $sql = "SELECT * FROM $user_table WHERE user_id=".$user_id;
  965. $res = Database::query($sql);
  966. if (Database::num_rows($res) > 0) {
  967. $user = Database::fetch_array($res);
  968. $t_uf = Database::get_main_table(TABLE_MAIN_USER_FIELD);
  969. $t_ufv = Database::get_main_table(TABLE_MAIN_USER_FIELD_VALUES);
  970. $sqlf = "SELECT * FROM $t_uf ORDER BY field_order";
  971. $resf = Database::query($sqlf);
  972. if (Database::num_rows($resf) > 0) {
  973. while ($rowf = Database::fetch_array($resf)) {
  974. $sqlv = "SELECT * FROM $t_ufv WHERE field_id = ".$rowf['id']." AND user_id = ".$user['user_id']." ORDER BY id DESC";
  975. $resv = Database::query($sqlv);
  976. if (Database::num_rows($resv) > 0) {
  977. //There should be only one value for a field and a user
  978. $rowv = Database::fetch_array($resv);
  979. $user['extra'][$rowf['field_variable']] = $rowv['field_value'];
  980. } else {
  981. $user['extra'][$rowf['field_variable']] = '';
  982. }
  983. }
  984. }
  985. return $user;
  986. }
  987. return false;
  988. }
  989. /**
  990. * Get the teacher list
  991. * @param int the course ID
  992. * @param array Content the list ID of user_id selected
  993. */
  994. //for survey
  995. // TODO: Ivan, 14-SEP-2009: It seems that this method is not used at all (it can be located in a test unit only. To be deprecated?
  996. public static function get_teacher_list($course_id, $sel_teacher = '')
  997. {
  998. $user_course_table = Database :: get_main_table(TABLE_MAIN_COURSE_USER);
  999. $user_table = Database :: get_main_table(TABLE_MAIN_USER);
  1000. $course_id = Database::escape_string($course_id);
  1001. $sql = "SELECT * FROM $user_table a, $user_course_table b
  1002. WHERE a.user_id=b.user_id AND b.status=1 AND b.course_code='$course_id'";
  1003. $sql_result = Database::query($sql);
  1004. echo "<select name=\"author\">";
  1005. while ($result = Database::fetch_array($sql_result)) {
  1006. if ($sel_teacher == $result['user_id'])
  1007. $selected = "selected";
  1008. echo "\n<option value=\"".$result['user_id']."\" $selected>".$result['firstname']."</option>";
  1009. }
  1010. echo "</select>";
  1011. }
  1012. /**
  1013. * Get user picture URL or path from user ID (returns an array).
  1014. * The return format is a complete path, enabling recovery of the directory
  1015. * with dirname() or the file with basename(). This also works for the
  1016. * functions dealing with the user's productions, as they are located in
  1017. * the same directory.
  1018. * @param integer User ID
  1019. * @param string Type of path to return (can be 'none', 'system', 'rel', 'web')
  1020. * @param bool Whether we want to have the directory name returned 'as if' there was a file or not (in the case we want to know which directory to create - otherwise no file means no split subdir)
  1021. * @param bool If we want that the function returns the /main/img/unknown.jpg image set it at true
  1022. * @return array Array of 2 elements: 'dir' and 'file' which contain the dir and file as the name implies if image does not exist it will return the unknow image if anonymous parameter is true if not it returns an empty er's
  1023. */
  1024. public static function get_user_picture_path_by_id($id, $type = 'none', $preview = false, $anonymous = false)
  1025. {
  1026. switch ($type) {
  1027. case 'system': // Base: absolute system path.
  1028. $base = api_get_path(SYS_CODE_PATH);
  1029. break;
  1030. case 'rel': // Base: semi-absolute web path (no server base).
  1031. $base = api_get_path(REL_CODE_PATH);
  1032. break;
  1033. case 'web': // Base: absolute web path.
  1034. $base = api_get_path(WEB_CODE_PATH);
  1035. break;
  1036. case 'none':
  1037. default: // Base: empty, the result path below will be relative.
  1038. $base = '';
  1039. }
  1040. if (empty($id) || empty($type)) {
  1041. return $anonymous ? array('dir' => $base.'img/', 'file' => 'unknown.jpg') : array('dir' => '', 'file' => '');
  1042. }
  1043. $user_id = intval($id);
  1044. $user_table = Database :: get_main_table(TABLE_MAIN_USER);
  1045. $sql = "SELECT picture_uri FROM $user_table WHERE user_id=".$user_id;
  1046. $res = Database::query($sql);
  1047. if (!Database::num_rows($res)) {
  1048. return $anonymous ? array('dir' => $base.'img/', 'file' => 'unknown.jpg') : array('dir' => '', 'file' => '');
  1049. }
  1050. $user = Database::fetch_array($res);
  1051. $picture_filename = trim($user['picture_uri']);
  1052. if (api_get_setting('split_users_upload_directory') === 'true') {
  1053. if (!empty($picture_filename) or $preview) {
  1054. $dir = $base.'upload/users/'.substr((string) $user_id, 0, 1).'/'.$user_id.'/';
  1055. } else {
  1056. $dir = $base.'upload/users/'.$user_id.'/';
  1057. }
  1058. } else {
  1059. $dir = $base.'upload/users/'.$user_id.'/';
  1060. }
  1061. if (empty($picture_filename) && $anonymous) {
  1062. return array('dir' => $base.'img/', 'file' => 'unknown.jpg');
  1063. }
  1064. return array('dir' => $dir, 'file' => $picture_filename);
  1065. }
  1066. /**
  1067. * Creates new user photos in various sizes of a user, or deletes user photos.
  1068. * Note: This method relies on configuration setting from main/inc/conf/profile.conf.php
  1069. * @param int $user_id The user internal identitfication number.
  1070. * @param string $file The common file name for the newly created photos.
  1071. * It will be checked and modified for compatibility with the file system.
  1072. * If full name is provided, path component is ignored.
  1073. * If an empty name is provided, then old user photos are deleted only,
  1074. * @see UserManager::delete_user_picture() as the prefered way for deletion.
  1075. * @param string $source_file The full system name of the image from which user photos will be created.
  1076. * @return string/bool Returns the resulting common file name of created images which usually should be stored in database.
  1077. * When deletion is recuested returns empty string. In case of internal error or negative validation returns FALSE.
  1078. */
  1079. public static function update_user_picture($user_id, $file = null, $source_file = null)
  1080. {
  1081. if (empty($user_id)) {
  1082. return false;
  1083. }
  1084. $delete = empty($file);
  1085. if (empty($source_file)) {
  1086. $source_file = $file;
  1087. }
  1088. // Configuration options about user photos.
  1089. require_once api_get_path(CONFIGURATION_PATH).'profile.conf.php';
  1090. // User-reserved directory where photos have to be placed.
  1091. $path_info = self::get_user_picture_path_by_id($user_id, 'system', true);
  1092. $path = $path_info['dir'];
  1093. // If this directory does not exist - we create it.
  1094. if (!file_exists($path)) {
  1095. @mkdir($path, api_get_permissions_for_new_directories(), true);
  1096. }
  1097. // The old photos (if any).
  1098. $old_file = $path_info['file'];
  1099. // Let us delete them.
  1100. if (!empty($old_file)) {
  1101. if (KEEP_THE_OLD_IMAGE_AFTER_CHANGE) {
  1102. $prefix = 'saved_'.date('Y_m_d_H_i_s').'_'.uniqid('').'_';
  1103. @rename($path.'small_'.$old_file, $path.$prefix.'small_'.$old_file);
  1104. @rename($path.'medium_'.$old_file, $path.$prefix.'medium_'.$old_file);
  1105. @rename($path.'big_'.$old_file, $path.$prefix.'big_'.$old_file);
  1106. @rename($path.$old_file, $path.$prefix.$old_file);
  1107. } else {
  1108. @unlink($path.'small_'.$old_file);
  1109. @unlink($path.'medium_'.$old_file);
  1110. @unlink($path.'big_'.$old_file);
  1111. @unlink($path.$old_file);
  1112. }
  1113. }
  1114. // Exit if only deletion has been requested. Return an empty picture name.
  1115. if ($delete) {
  1116. return '';
  1117. }
  1118. // Validation 2.
  1119. $allowed_types = array('jpg', 'jpeg', 'png', 'gif');
  1120. $file = str_replace('\\', '/', $file);
  1121. $filename = (($pos = strrpos($file, '/')) !== false) ? substr($file, $pos + 1) : $file;
  1122. $extension = strtolower(substr(strrchr($filename, '.'), 1));
  1123. if (!in_array($extension, $allowed_types)) {
  1124. return false;
  1125. }
  1126. // This is the common name for the new photos.
  1127. if (KEEP_THE_NAME_WHEN_CHANGE_IMAGE && !empty($old_file)) {
  1128. $old_extension = strtolower(substr(strrchr($old_file, '.'), 1));
  1129. $filename = in_array($old_extension, $allowed_types) ? substr($old_file, 0, -strlen($old_extension)) : $old_file;
  1130. $filename = (substr($filename, -1) == '.') ? $filename.$extension : $filename.'.'.$extension;
  1131. } else {
  1132. $filename = replace_dangerous_char($filename);
  1133. if (PREFIX_IMAGE_FILENAME_WITH_UID) {
  1134. $filename = uniqid('').'_'.$filename;
  1135. }
  1136. // We always prefix user photos with user ids, so on setting
  1137. // api_get_setting('split_users_upload_directory') === 'true'
  1138. // the correspondent directories to be found successfully.
  1139. $filename = $user_id.'_'.$filename;
  1140. }
  1141. // Storing the new photos in 4 versions with various sizes.
  1142. $small = self::resize_picture($source_file, 22);
  1143. $medium = self::resize_picture($source_file, 85);
  1144. $normal = self::resize_picture($source_file, 200);
  1145. $big = new Image($source_file); // This is the original picture.
  1146. $ok = $small && $small->send_image($path.'small_'.$filename) &&
  1147. $medium && $medium->send_image($path.'medium_'.$filename) &&
  1148. $normal && $normal->send_image($path.$filename) &&
  1149. $big && $big->send_image($path.'big_'.$filename);
  1150. return $ok ? $filename : false;
  1151. }
  1152. /**
  1153. * Deletes user photos.
  1154. * Note: This method relies on configuration setting from main/inc/conf/profile.conf.php
  1155. * @param int $user_id The user internal identitfication number.
  1156. * @return string/bool Returns empty string on success, FALSE on error.
  1157. */
  1158. public static function delete_user_picture($user_id)
  1159. {
  1160. return self::update_user_picture($user_id);
  1161. }
  1162. /**
  1163. * Returns an XHTML formatted list of productions for a user, or FALSE if he
  1164. * doesn't have any.
  1165. *
  1166. * If there has been a request to remove a production, the function will return
  1167. * without building the list unless forced to do so by the optional second
  1168. * parameter. This increases performance by avoiding to read through the
  1169. * productions on the filesystem before the removal request has been carried
  1170. * out because they'll have to be re-read afterwards anyway.
  1171. *
  1172. * @param $user_id User id
  1173. * @param $force Optional parameter to force building after a removal request
  1174. * @return A string containing the XHTML code to dipslay the production list, or FALSE
  1175. */
  1176. public static function build_production_list($user_id, $force = false, $showdelete = false)
  1177. {
  1178. if (!$force && !empty($_POST['remove_production'])) {
  1179. return true; // postpone reading from the filesystem
  1180. }
  1181. $productions = self::get_user_productions($user_id);
  1182. if (empty($productions)) {
  1183. return false;
  1184. }
  1185. $production_path = self::get_user_picture_path_by_id($user_id, 'web', true);
  1186. $production_dir = $production_path['dir'].$user_id.'/';
  1187. $del_image = api_get_path(WEB_CODE_PATH).'img/delete.gif';
  1188. $del_text = get_lang('Delete');
  1189. $production_list = '';
  1190. if (count($productions) > 0) {
  1191. $production_list = '<ul id="productions">';
  1192. foreach ($productions as $file) {
  1193. $production_list .= '<li><a href="'.$production_dir.urlencode($file).'" target="_blank">'.htmlentities($file).'</a>';
  1194. if ($showdelete) {
  1195. $production_list .= '<input type="image" name="remove_production['.urlencode($file).']" src="'.$del_image.'" alt="'.$del_text.'" title="'.$del_text.' '.htmlentities($file).'" onclick="javascript: return confirmation(\''.htmlentities($file).'\');" /></li>';
  1196. }
  1197. }
  1198. $production_list .= '</ul>';
  1199. }
  1200. return $production_list;
  1201. }
  1202. /**
  1203. * Returns an array with the user's productions.
  1204. *
  1205. * @param $user_id User id
  1206. * @return An array containing the user's productions
  1207. */
  1208. public static function get_user_productions($user_id)
  1209. {
  1210. $production_path = self::get_user_picture_path_by_id($user_id, 'system', true);
  1211. $production_repository = $production_path['dir'].$user_id.'/';
  1212. $productions = array();
  1213. if (is_dir($production_repository)) {
  1214. $handle = opendir($production_repository);
  1215. while ($file = readdir($handle)) {
  1216. if ($file == '.' || $file == '..' || $file == '.htaccess' || is_dir($production_repository.$file)) {
  1217. continue; // skip current/parent directory and .htaccess
  1218. }
  1219. if (preg_match('/('.$user_id.'|[0-9a-f]{13}|saved)_.+\.(png|jpg|jpeg|gif)$/i', $file)) {
  1220. // User's photos should not be listed as productions.
  1221. continue;
  1222. }
  1223. $productions[] = $file;
  1224. }
  1225. }
  1226. return $productions; // can be an empty array
  1227. }
  1228. /**
  1229. * Remove a user production.
  1230. *
  1231. * @param $user_id User id
  1232. * @param $production The production to remove
  1233. */
  1234. public static function remove_user_production($user_id, $production)
  1235. {
  1236. $production_path = self::get_user_picture_path_by_id($user_id, 'system', true);
  1237. $production_file = $production_path['dir'].$user_id.'/'.$production;
  1238. if (is_file($production_file)) {
  1239. unlink($production_file);
  1240. return true;
  1241. }
  1242. return false;
  1243. }
  1244. /**
  1245. * Update an extra field. This function is called when a user changes his/her profile
  1246. * and by consequence fills or edits his/her extra fields.
  1247. *
  1248. * @param integer Field ID
  1249. * @param array Database columns and their new value
  1250. * @return boolean true if field updated, false otherwise
  1251. */
  1252. public static function update_extra_field($fid, $columns)
  1253. {
  1254. //TODO check that values added are values proposed for enumerated field types
  1255. $t_uf = Database::get_main_table(TABLE_MAIN_USER_FIELD);
  1256. $fid = Database::escape_string($fid);
  1257. $sqluf = "UPDATE $t_uf SET ";
  1258. $known_fields = array(
  1259. 'id',
  1260. 'field_variable',
  1261. 'field_type',
  1262. 'field_display_text',
  1263. 'field_default_value',
  1264. 'field_order',
  1265. 'field_visible',
  1266. 'field_changeable',
  1267. 'field_filter'
  1268. );
  1269. $safecolumns = array();
  1270. foreach ($columns as $index => $newval) {
  1271. if (in_array($index, $known_fields)) {
  1272. $safecolumns[$index] = Database::escape_string($newval);
  1273. $sqluf .= $index." = '".$safecolumns[$index]."', ";
  1274. }
  1275. }
  1276. $time = time();
  1277. $sqluf .= " tms = FROM_UNIXTIME($time) WHERE id='$fid'";
  1278. $resuf = Database::query($sqluf);
  1279. return $resuf;
  1280. }
  1281. /**
  1282. * Update an extra field value for a given user
  1283. * @param integer User ID
  1284. * @param string Field variable name
  1285. * @param string Field value
  1286. * @return boolean true if field updated, false otherwise
  1287. */
  1288. public static function update_extra_field_value($user_id, $fname, $fvalue = '')
  1289. {
  1290. //TODO check that values added are values proposed for enumerated field types
  1291. $t_uf = Database::get_main_table(TABLE_MAIN_USER_FIELD);
  1292. $t_ufo = Database::get_main_table(TABLE_MAIN_USER_FIELD_OPTIONS);
  1293. $t_ufv = Database::get_main_table(TABLE_MAIN_USER_FIELD_VALUES);
  1294. $fname = Database::escape_string($fname);
  1295. if ($user_id != strval(intval($user_id)))
  1296. return false;
  1297. if ($user_id === false)
  1298. return false;
  1299. $fvalues = '';
  1300. //echo '<pre>'; print_r($fvalue);
  1301. if (is_array($fvalue)) {
  1302. foreach ($fvalue as $val) {
  1303. $fvalues .= Database::escape_string($val).';';
  1304. }
  1305. if (!empty($fvalues)) {
  1306. $fvalues = substr($fvalues, 0, -1);
  1307. }
  1308. } else {
  1309. $fvalues = Database::escape_string($fvalue);
  1310. }
  1311. $sqluf = "SELECT * FROM $t_uf WHERE field_variable='$fname'";
  1312. $resuf = Database::query($sqluf);
  1313. if (Database::num_rows($resuf) == 1) {
  1314. //ok, the field exists
  1315. // Check if enumerated field, if the option is available
  1316. $rowuf = Database::fetch_array($resuf);
  1317. switch ($rowuf['field_type']) {
  1318. case self::USER_FIELD_TYPE_TAG :
  1319. //4. Tags are process here comes from main/auth/profile.php
  1320. UserManager::process_tags(explode(';', $fvalues), $user_id, $rowuf['id']);
  1321. return true;
  1322. break;
  1323. case self::USER_FIELD_TYPE_RADIO:
  1324. case self::USER_FIELD_TYPE_SELECT:
  1325. case self::USER_FIELD_TYPE_SELECT_MULTIPLE:
  1326. $sqluo = "SELECT * FROM $t_ufo WHERE field_id = ".$rowuf['id'];
  1327. $resuo = Database::query($sqluo);
  1328. $values = explode(';', $fvalues);
  1329. if (Database::num_rows($resuo) > 0) {
  1330. $check = false;
  1331. while ($rowuo = Database::fetch_array($resuo)) {
  1332. if (in_array($rowuo['option_value'], $values)) {
  1333. $check = true;
  1334. break;
  1335. }
  1336. }
  1337. if (!$check) {
  1338. return false; //option value not found
  1339. }
  1340. } else {
  1341. return false; //enumerated type but no option found
  1342. }
  1343. break;
  1344. case 1:
  1345. case 2:
  1346. default:
  1347. break;
  1348. }
  1349. $tms = time();
  1350. $sqlufv = "SELECT * FROM $t_ufv WHERE user_id = $user_id AND field_id = ".$rowuf['id']." ORDER BY id";
  1351. $resufv = Database::query($sqlufv);
  1352. $n = Database::num_rows($resufv);
  1353. if ($n > 1) {
  1354. //problem, we already have to values for this field and user combination - keep last one
  1355. while ($rowufv = Database::fetch_array($resufv)) {
  1356. if ($n > 1) {
  1357. $sqld = "DELETE FROM $t_ufv WHERE id = ".$rowufv['id'];
  1358. Database::query($sqld);
  1359. $n--;
  1360. }
  1361. $rowufv = Database::fetch_array($resufv);
  1362. if ($rowufv['field_value'] != $fvalues) {
  1363. $sqlu = "UPDATE $t_ufv SET field_value = '$fvalues', tms = FROM_UNIXTIME($tms) WHERE id = ".$rowufv['id'];
  1364. $resu = Database::query($sqlu);
  1365. return($resu ? true : false);
  1366. }
  1367. return true;
  1368. }
  1369. } elseif ($n == 1) {
  1370. //we need to update the current record
  1371. $rowufv = Database::fetch_array($resufv);
  1372. if ($rowufv['field_value'] != $fvalues) {
  1373. // If the new field is empty, delete it
  1374. if ($fvalues == '') {
  1375. $sql_query = "DELETE FROM $t_ufv WHERE id = ".$rowufv['id'].";";
  1376. } else {
  1377. // Otherwise update it
  1378. $sql_query = "UPDATE $t_ufv SET field_value = '$fvalues', tms = FROM_UNIXTIME($tms) WHERE id = ".$rowufv['id'];
  1379. }
  1380. $resu = Database::query($sql_query);
  1381. return($resu ? true : false);
  1382. }
  1383. return true;
  1384. } else {
  1385. $sqli = "INSERT INTO $t_ufv (user_id,field_id,field_value,tms) ".
  1386. "VALUES ($user_id,".$rowuf['id'].",'$fvalues',FROM_UNIXTIME($tms))";
  1387. $resi = Database::query($sqli);
  1388. return($resi ? true : false);
  1389. }
  1390. } else {
  1391. return false; //field not found
  1392. }
  1393. }
  1394. /**
  1395. * Get an array of extra fieds with field details (type, default value and options)
  1396. * @param integer Offset (from which row)
  1397. * @param integer Number of items
  1398. * @param integer Column on which sorting is made
  1399. * @param string Sorting direction
  1400. * @param boolean Optional. Whether we get all the fields or just the visible ones
  1401. * @param int Optional. Whether we get all the fields with field_filter 1 or 0 or everything
  1402. * @return array Extra fields details (e.g. $list[2]['type'], $list[4]['options'][2]['title']
  1403. */
  1404. public static function get_extra_fields($from = 0, $number_of_items = 0, $column = 5, $direction = 'ASC', $all_visibility = true, $field_filter = null)
  1405. {
  1406. $fields = array();
  1407. $t_uf = Database :: get_main_table(TABLE_MAIN_USER_FIELD);
  1408. $t_ufo = Database :: get_main_table(TABLE_MAIN_USER_FIELD_OPTIONS);
  1409. $columns = array('id', 'field_variable', 'field_type', 'field_display_text', 'field_default_value', 'field_order', 'field_filter', 'tms');
  1410. $column = intval($column);
  1411. $sort_direction = '';
  1412. if (in_array(strtoupper($direction), array('ASC', 'DESC'))) {
  1413. $sort_direction = strtoupper($direction);
  1414. }
  1415. $sqlf = "SELECT * FROM $t_uf WHERE 1 = 1 ";
  1416. if (!$all_visibility) {
  1417. $sqlf .= " AND field_visible = 1 ";
  1418. }
  1419. if (!is_null($field_filter)) {
  1420. $field_filter = intval($field_filter);
  1421. $sqlf .= " AND field_filter = $field_filter ";
  1422. }
  1423. $sqlf .= " ORDER BY ".$columns[$column]." $sort_direction ";
  1424. if ($number_of_items != 0) {
  1425. $sqlf .= " LIMIT ".Database::escape_string($from).','.Database::escape_string($number_of_items);
  1426. }
  1427. $resf = Database::query($sqlf);
  1428. if (Database::num_rows($resf) > 0) {
  1429. while ($rowf = Database::fetch_array($resf)) {
  1430. $fields[$rowf['id']] = array(
  1431. 0 => $rowf['id'],
  1432. 1 => $rowf['field_variable'],
  1433. 2 => $rowf['field_type'],
  1434. //3 => (empty($rowf['field_display_text']) ? '' : get_lang($rowf['field_display_text'], '')),
  1435. // Temporarily removed auto-translation. Need update to get_lang() to know if translation exists (todo)
  1436. // Ivan, 15-SEP-2009: get_lang() has been modified accordingly in order this issue to be solved.
  1437. 3 => (empty($rowf['field_display_text']) ? '' : $rowf['field_display_text']),
  1438. 4 => $rowf['field_default_value'],
  1439. 5 => $rowf['field_order'],
  1440. 6 => $rowf['field_visible'],
  1441. 7 => $rowf['field_changeable'],
  1442. 8 => $rowf['field_filter'],
  1443. 9 => array()
  1444. );
  1445. $sqlo = "SELECT * FROM $t_ufo WHERE field_id = ".$rowf['id']." ORDER BY option_order ASC";
  1446. $reso = Database::query($sqlo);
  1447. if (Database::num_rows($reso) > 0) {
  1448. while ($rowo = Database::fetch_array($reso)) {
  1449. $fields[$rowf['id']][9][$rowo['id']] = array(
  1450. 0 => $rowo['id'],
  1451. 1 => $rowo['option_value'],
  1452. //2 => (empty($rowo['option_display_text']) ? '' : get_lang($rowo['option_display_text'], '')),
  1453. 2 => (empty($rowo['option_display_text']) ? '' : $rowo['option_display_text']),
  1454. 3 => $rowo['option_order']
  1455. );
  1456. }
  1457. }
  1458. }
  1459. }
  1460. return $fields;
  1461. }
  1462. /**
  1463. * Get the list of options attached to an extra field
  1464. * @param string $fieldname the name of the field
  1465. * @return array the list of options
  1466. */
  1467. public static function get_extra_field_options($field_name)
  1468. {
  1469. $t_uf = Database :: get_main_table(TABLE_MAIN_USER_FIELD);
  1470. $t_ufo = Database :: get_main_table(TABLE_MAIN_USER_FIELD_OPTIONS);
  1471. $sql = 'SELECT options.*
  1472. FROM '.$t_ufo.' options
  1473. INNER JOIN '.$t_uf.' fields
  1474. ON fields.id = options.field_id
  1475. AND fields.field_variable="'.Database::escape_string($field_name).'"';
  1476. $rs = Database::query($sql);
  1477. return Database::store_result($rs);
  1478. }
  1479. /**
  1480. * Get the number of extra fields currently recorded
  1481. * @param boolean Optional switch. true (default) returns all fields, false returns only visible fields
  1482. * @return integer Number of fields
  1483. */
  1484. public static function get_number_of_extra_fields($all_visibility = true)
  1485. {
  1486. $t_uf = Database :: get_main_table(TABLE_MAIN_USER_FIELD);
  1487. $sqlf = "SELECT * FROM $t_uf ";
  1488. if (!$all_visibility) {
  1489. $sqlf .= " WHERE field_visible = 1 ";
  1490. }
  1491. $sqlf .= " ORDER BY field_order";
  1492. $resf = Database::query($sqlf);
  1493. return Database::num_rows($resf);
  1494. }
  1495. /**
  1496. * Creates a new extra field
  1497. * @param string Field's internal variable name
  1498. * @param int Field's type
  1499. * @param string Field's language var name
  1500. * @param string Field's default value
  1501. * @param string Optional comma-separated list of options to provide for select and radio
  1502. * @return int new user id - if the new user creation succeeds, false otherwise
  1503. */
  1504. public static function create_extra_field($fieldvarname, $fieldtype, $fieldtitle, $fielddefault, $fieldoptions = '')
  1505. {
  1506. // database table definition
  1507. $table_field = Database::get_main_table(TABLE_MAIN_USER_FIELD);
  1508. $table_field_options = Database::get_main_table(TABLE_MAIN_USER_FIELD_OPTIONS);
  1509. // First check wether the login already exists
  1510. if (self::is_extra_field_available($fieldvarname)) {
  1511. return api_set_failure('login-pass already taken');
  1512. }
  1513. $sql = "SELECT MAX(field_order) FROM $table_field";
  1514. $res = Database::query($sql);
  1515. $order = 0;
  1516. if (Database::num_rows($res) > 0) {
  1517. $row = Database::fetch_array($res);
  1518. $order = $row[0] + 1;
  1519. }
  1520. $time = time();
  1521. $sql = "INSERT INTO $table_field
  1522. SET field_type = '".Database::escape_string($fieldtype)."',
  1523. field_variable = '".Database::escape_string($fieldvarname)."',
  1524. field_display_text = '".Database::escape_string($fieldtitle)."',
  1525. field_default_value = '".Database::escape_string($fielddefault)."',
  1526. field_order = '$order',
  1527. tms = FROM_UNIXTIME($time)";
  1528. $result = Database::query($sql);
  1529. if ($result) {
  1530. //echo "id returned";
  1531. $return = Database::insert_id();
  1532. event_system(LOG_USER_FIELD_CREATE, LOG_USER_FIELD_VARIABLE, Database::escape_string($fieldvarname));
  1533. } else {
  1534. //echo "false - failed" ;
  1535. return false;
  1536. }
  1537. if (!empty($fieldoptions) && in_array($fieldtype, array(self::USER_FIELD_TYPE_RADIO, self::USER_FIELD_TYPE_SELECT, self::USER_FIELD_TYPE_SELECT_MULTIPLE, self::USER_FIELD_TYPE_DOUBLE_SELECT))) {
  1538. if ($fieldtype == self::USER_FIELD_TYPE_DOUBLE_SELECT) {
  1539. $twolist = explode('|', $fieldoptions);
  1540. $counter = 0;
  1541. foreach ($twolist as $individual_list) {
  1542. $splitted_individual_list = explode(';', $individual_list);
  1543. foreach ($splitted_individual_list as $individual_list_option) {
  1544. //echo 'counter:'.$counter;
  1545. if ($counter == 0) {
  1546. $list[] = $individual_list_option;
  1547. } else {
  1548. $list[] = str_repeat('*', $counter).$individual_list_option;
  1549. }
  1550. }
  1551. $counter++;
  1552. }
  1553. } else {
  1554. $list = explode(';', $fieldoptions);
  1555. }
  1556. foreach ($list as $option) {
  1557. $option = Database::escape_string($option);
  1558. $sql = "SELECT * FROM $table_field_options WHERE field_id = $return AND option_value = '".$option."'";
  1559. $res = Database::query($sql);
  1560. if (Database::num_rows($res) > 0) {
  1561. //the option already exists, do nothing
  1562. } else {
  1563. $sql = "SELECT MAX(option_order) FROM $table_field_options WHERE field_id = $return";
  1564. $res = Database::query($sql);
  1565. $max = 1;
  1566. if (Database::num_rows($res) > 0) {
  1567. $row = Database::fetch_array($res);
  1568. $max = $row[0] + 1;
  1569. }
  1570. $time = time();
  1571. $sql = "INSERT INTO $table_field_options (field_id,option_value,option_display_text,option_order,tms)
  1572. VALUES ($return,'$option','$option',$max,FROM_UNIXTIME($time))";
  1573. $res = Database::query($sql);
  1574. if ($res === false) {
  1575. $return = false;
  1576. }
  1577. }
  1578. }
  1579. }
  1580. return $return;
  1581. }
  1582. /**
  1583. * Save the changes in the definition of the extra user profile field
  1584. * The function is called after you (as admin) decide to store the changes you have made to one of the fields you defined
  1585. *
  1586. * There is quite some logic in this field
  1587. * 1. store the changes to the field (tupe, name, label, default text)
  1588. * 2. remove the options and the choices of the users from the database that no longer occur in the form field 'possible values'. We should only remove
  1589. * the options (and choices) that do no longer have to appear. We cannot remove all options and choices because if you remove them all
  1590. * and simply re-add them all then all the user who have already filled this form will loose their selected value.
  1591. * 3. we add the options that are newly added
  1592. *
  1593. * <code> current options are a;b;c and the user changes this to a;b;x (removing c and adding x)
  1594. * we first remove c (and also the entry in the option_value table for the users who have chosen this)
  1595. * we then add x
  1596. * a and b are neither removed nor added
  1597. * </code>
  1598. * @param integer $fieldid the id of the field we are editing
  1599. * @param string $fieldvarname the internal variable name of the field
  1600. * @param int $fieldtype the type of the field
  1601. * @param string $fieldtitle the title of the field
  1602. * @param string $fielddefault the default value of the field
  1603. * @param string $fieldoptions Optional comma-separated list of options to provide for select and radio
  1604. * @return boolean true
  1605. *
  1606. *
  1607. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University, Belgium
  1608. * @version July 2008
  1609. * @since v1.8.6
  1610. */
  1611. public static function save_extra_field_changes($fieldid, $fieldvarname, $fieldtype, $fieldtitle, $fielddefault, $fieldoptions = '')
  1612. {
  1613. // database table definition
  1614. $table_field = Database::get_main_table(TABLE_MAIN_USER_FIELD);
  1615. $table_field_options = Database::get_main_table(TABLE_MAIN_USER_FIELD_OPTIONS);
  1616. $table_field_options_values = Database::get_main_table(TABLE_MAIN_USER_FIELD_VALUES);
  1617. // we first update the field definition with the new values
  1618. $time = time();
  1619. $sql = "UPDATE $table_field
  1620. SET field_type = '".Database::escape_string($fieldtype)."',
  1621. field_variable = '".Database::escape_string($fieldvarname)."',
  1622. field_display_text = '".Database::escape_string($fieldtitle)."',
  1623. field_default_value = '".Database::escape_string($fielddefault)."',
  1624. tms = FROM_UNIXTIME($time)
  1625. WHERE id = '".Database::escape_string($fieldid)."'";
  1626. $result = Database::query($sql);
  1627. // we create an array with all the options (will be used later in the script)
  1628. if ($fieldtype == self::USER_FIELD_TYPE_DOUBLE_SELECT) {
  1629. $twolist = explode('|', $fieldoptions);
  1630. $counter = 0;
  1631. foreach ($twolist as $individual_list) {
  1632. $splitted_individual_list = explode(';', $individual_list);
  1633. foreach ($splitted_individual_list as $individual_list_option) {
  1634. //echo 'counter:'.$counter;
  1635. if ($counter == 0) {
  1636. $list[] = trim($individual_list_option);
  1637. } else {
  1638. $list[] = str_repeat('*', $counter).trim($individual_list_option);
  1639. }
  1640. }
  1641. $counter++;
  1642. }
  1643. } else {
  1644. $templist = explode(';', $fieldoptions);
  1645. $list = array_map('trim', $templist);
  1646. }
  1647. // Remove all the field options (and also the choices of the user) that are NOT in the new list of options
  1648. $sql = "SELECT * FROM $table_field_options WHERE option_value NOT IN ('".implode("','", $list)."') AND field_id = '".Database::escape_string($fieldid)."'";
  1649. $result = Database::query($sql);
  1650. $return['deleted_options'] = 0;
  1651. while ($row = Database::fetch_array($result)) {
  1652. // deleting the option
  1653. $sql_delete_option = "DELETE FROM $table_field_options WHERE id='".Database::escape_string($row['id'])."'";
  1654. Database::query($sql_delete_option);
  1655. $return['deleted_options']++;
  1656. // deleting the answer of the user who has chosen this option
  1657. $sql_delete_option_value = "DELETE FROM $table_field_options_values
  1658. WHERE field_id = '".Database::escape_string($fieldid)."' AND field_value = '".Database::escape_string($row['option_value'])."'";
  1659. Database::query($sql_delete_option_value);
  1660. $return['deleted_option_values'] = $return['deleted_option_values'] + Database::affected_rows();
  1661. }
  1662. // we now try to find the field options that are newly added
  1663. $sql = "SELECT * FROM $table_field_options WHERE field_id = '".Database::escape_string($fieldid)."'";
  1664. $result = Database::query($sql);
  1665. while ($row = Database::fetch_array($result)) {
  1666. // we remove every option that is already in the database from the $list
  1667. if (in_array(trim($row['option_display_text']), $list)) {
  1668. $key = array_search(trim($row['option_display_text']), $list);
  1669. unset($list[$key]);
  1670. }
  1671. }
  1672. // we store the new field options in the database
  1673. foreach ($list as $key => $option) {
  1674. $sql = "SELECT MAX(option_order) FROM $table_field_options WHERE field_id = '".Database::escape_string($fieldid)."'";
  1675. $res = Database::query($sql);
  1676. $max = 1;
  1677. if (Database::num_rows($res) > 0) {
  1678. $row = Database::fetch_array($res);
  1679. $max = $row[0] + 1;
  1680. }
  1681. $time = time();
  1682. $sql = "INSERT INTO $table_field_options (field_id,option_value,option_display_text,option_order,tms)
  1683. VALUES ('".Database::escape_string($fieldid)."','".Database::escape_string($option)."','".Database::escape_string($option)."',$max,FROM_UNIXTIME($time))";
  1684. $result = Database::query($sql);
  1685. }
  1686. return true;
  1687. }
  1688. /**
  1689. * Check if a field is available
  1690. * @param string the wanted fieldname
  1691. * @return boolean true if the wanted username is available
  1692. */
  1693. public static function is_extra_field_available($fieldname)
  1694. {
  1695. $t_uf = Database :: get_main_table(TABLE_MAIN_USER_FIELD);
  1696. $sql = "SELECT * FROM $t_uf WHERE field_variable = '".Database::escape_string($fieldname)."'";
  1697. $res = Database::query($sql);
  1698. return Database::num_rows($res) > 0;
  1699. }
  1700. /**
  1701. * Gets user extra fields data
  1702. * @param integer User ID
  1703. * @param boolean Whether to prefix the fields indexes with "extra_" (might be used by formvalidator)
  1704. * @param boolean Whether to return invisible fields as well
  1705. * @param boolean Whether to split multiple-selection fields or not
  1706. * @return array Array of fields => value for the given user
  1707. */
  1708. public static function get_extra_user_data($user_id, $prefix = false, $all_visibility = true, $splitmultiple = false, $field_filter = null)
  1709. {
  1710. // A sanity check.
  1711. if (empty($user_id)) {
  1712. $user_id = 0;
  1713. } else {
  1714. if ($user_id != strval(intval($user_id)))
  1715. return array();
  1716. }
  1717. $extra_data = array();
  1718. $t_uf = Database::get_main_table(TABLE_MAIN_USER_FIELD);
  1719. $t_ufv = Database::get_main_table(TABLE_MAIN_USER_FIELD_VALUES);
  1720. $user_id = Database::escape_string($user_id);
  1721. $sql = "SELECT f.id as id, f.field_variable as fvar, f.field_type as type FROM $t_uf f ";
  1722. $filter_cond = '';
  1723. if (!$all_visibility) {
  1724. if (isset($field_filter)) {
  1725. $field_filter = intval($field_filter);
  1726. $filter_cond .= " AND field_filter = $field_filter ";
  1727. }
  1728. $sql .= " WHERE f.field_visible = 1 $filter_cond ";
  1729. } else {
  1730. if (isset($field_filter)) {
  1731. $field_filter = intval($field_filter);
  1732. $sql .= " WHERE field_filter = $field_filter ";
  1733. }
  1734. }
  1735. $sql .= " ORDER BY f.field_order";
  1736. $res = Database::query($sql);
  1737. if (Database::num_rows($res) > 0) {
  1738. while ($row = Database::fetch_array($res)) {
  1739. if ($row['type'] == self::USER_FIELD_TYPE_TAG) {
  1740. $tags = self::get_user_tags_to_string($user_id, $row['id'], false);
  1741. $extra_data['extra_'.$row['fvar']] = $tags;
  1742. } else {
  1743. $sqlu = "SELECT field_value as fval FROM $t_ufv WHERE field_id=".$row['id']." AND user_id = ".$user_id;
  1744. $resu = Database::query($sqlu);
  1745. $fval = '';
  1746. // get default value
  1747. $sql_df = "SELECT field_default_value as fval_df ".
  1748. " FROM $t_uf ".
  1749. " WHERE id=".$row['id'];
  1750. $res_df = Database::query($sql_df);
  1751. if (Database::num_rows($resu) > 0) {
  1752. $rowu = Database::fetch_array($resu);
  1753. $fval = $rowu['fval'];
  1754. if ($row['type'] == self::USER_FIELD_TYPE_SELECT_MULTIPLE) {
  1755. $fval = explode(';', $rowu['fval']);
  1756. }
  1757. } else {
  1758. $row_df = Database::fetch_array($res_df);
  1759. $fval = $row_df['fval_df'];
  1760. }
  1761. // We get here (and fill the $extra_data array) even if there is no user with data (we fill it with default values)
  1762. if ($prefix) {
  1763. if ($row['type'] == self::USER_FIELD_TYPE_RADIO) {
  1764. $extra_data['extra_'.$row['fvar']]['extra_'.$row['fvar']] = $fval;
  1765. } else {
  1766. $extra_data['extra_'.$row['fvar']] = $fval;
  1767. }
  1768. } else {
  1769. if ($row['type'] == self::USER_FIELD_TYPE_RADIO) {
  1770. $extra_data['extra_'.$row['fvar']]['extra_'.$row['fvar']] = $fval;
  1771. } else {
  1772. $extra_data[$row['fvar']] = $fval;
  1773. }
  1774. }
  1775. }
  1776. }
  1777. }
  1778. return $extra_data;
  1779. }
  1780. /** Get extra user data by field
  1781. * @param int user ID
  1782. * @param string the internal variable name of the field
  1783. * @return array with extra data info of a user i.e array('field_variable'=>'value');
  1784. */
  1785. public static function get_extra_user_data_by_field($user_id, $field_variable, $prefix = false, $all_visibility = true, $splitmultiple = false)
  1786. {
  1787. // A sanity check.
  1788. if (empty($user_id)) {
  1789. $user_id = 0;
  1790. } else {
  1791. if ($user_id != strval(intval($user_id)))
  1792. return array();
  1793. }
  1794. $extra_data = array();
  1795. $t_uf = Database::get_main_table(TABLE_MAIN_USER_FIELD);
  1796. $t_ufv = Database::get_main_table(TABLE_MAIN_USER_FIELD_VALUES);
  1797. $user_id = Database::escape_string($user_id);
  1798. $sql = "SELECT f.id as id, f.field_variable as fvar, f.field_type as type FROM $t_uf f ";
  1799. $sql .= " WHERE f.field_variable = '$field_variable' ";
  1800. if (!$all_visibility) {
  1801. $sql .= " AND f.field_visible = 1 ";
  1802. }
  1803. $sql .= " ORDER BY f.field_order";
  1804. $res = Database::query($sql);
  1805. if (Database::num_rows($res) > 0) {
  1806. while ($row = Database::fetch_array($res)) {
  1807. $sqlu = "SELECT field_value as fval ".
  1808. " FROM $t_ufv ".
  1809. " WHERE field_id=".$row['id']."".
  1810. " AND user_id=".$user_id;
  1811. $resu = Database::query($sqlu);
  1812. $fval = '';
  1813. if (Database::num_rows($resu) > 0) {
  1814. $rowu = Database::fetch_array($resu);
  1815. $fval = $rowu['fval'];
  1816. if ($row['type'] == self::USER_FIELD_TYPE_SELECT_MULTIPLE) {
  1817. $fval = explode(';', $rowu['fval']);
  1818. }
  1819. }
  1820. if ($prefix) {
  1821. $extra_data['extra_'.$row['fvar']] = $fval;
  1822. } else {
  1823. $extra_data[$row['fvar']] = $fval;
  1824. }
  1825. }
  1826. }
  1827. return $extra_data;
  1828. }
  1829. /**
  1830. * Get the extra field information for a certain field (the options as well)
  1831. * @param int The name of the field we want to know everything about
  1832. * @return array Array containing all the information about the extra profile field
  1833. * (first level of array contains field details, then 'options' sub-array contains options details,
  1834. * as returned by the database)
  1835. * @author Julio Montoya
  1836. * @since v1.8.6
  1837. */
  1838. public static function get_extra_field_information_by_name($field_variable, $fuzzy = false)
  1839. {
  1840. // database table definition
  1841. $table_field = Database::get_main_table(TABLE_MAIN_USER_FIELD);
  1842. $table_field_options = Database::get_main_table(TABLE_MAIN_USER_FIELD_OPTIONS);
  1843. // all the information of the field
  1844. $sql = "SELECT * FROM $table_field WHERE field_variable='".Database::escape_string($field_variable)."'";
  1845. $result = Database::query($sql);
  1846. $return = Database::fetch_array($result);
  1847. // all the options of the field
  1848. $sql = "SELECT * FROM $table_field_options WHERE field_id='".Database::escape_string($return['id'])."' ORDER BY option_order ASC";
  1849. $result = Database::query($sql);
  1850. while ($row = Database::fetch_array($result)) {
  1851. $return['options'][$row['id']] = $row;
  1852. }
  1853. return $return;
  1854. }
  1855. public static function get_all_extra_field_by_type($field_type)
  1856. {
  1857. // database table definition
  1858. $table_field = Database::get_main_table(TABLE_MAIN_USER_FIELD);
  1859. // all the information of the field
  1860. $sql = "SELECT * FROM $table_field WHERE field_type='".Database::escape_string($field_type)."'";
  1861. $result = Database::query($sql);
  1862. $return = array();
  1863. while ($row = Database::fetch_array($result)) {
  1864. $return[] = $row['id'];
  1865. }
  1866. return $return;
  1867. }
  1868. /**
  1869. * Get all the extra field information of a certain field (also the options)
  1870. *
  1871. * @param int $field_name the name of the field we want to know everything of
  1872. * @return array $return containing all th information about the extra profile field
  1873. * @author Julio Montoya
  1874. * @since v1.8.6
  1875. */
  1876. public static function get_extra_field_information($field_id)
  1877. {
  1878. // database table definition
  1879. $table_field = Database::get_main_table(TABLE_MAIN_USER_FIELD);
  1880. $table_field_options = Database::get_main_table(TABLE_MAIN_USER_FIELD_OPTIONS);
  1881. // all the information of the field
  1882. $sql = "SELECT * FROM $table_field WHERE id='".Database::escape_string($field_id)."'";
  1883. $result = Database::query($sql);
  1884. $return = Database::fetch_array($result);
  1885. // all the options of the field
  1886. $sql = "SELECT * FROM $table_field_options WHERE field_id='".Database::escape_string($field_id)."' ORDER BY option_order ASC";
  1887. $result = Database::query($sql);
  1888. while ($row = Database::fetch_array($result)) {
  1889. $return['options'][$row['id']] = $row;
  1890. }
  1891. return $return;
  1892. }
  1893. /** Get extra user data by value
  1894. * @param string the internal variable name of the field
  1895. * @param string the internal value of the field
  1896. * @return array with extra data info of a user i.e array('field_variable'=>'value');
  1897. */
  1898. public static function get_extra_user_data_by_value($field_variable, $field_value, $all_visibility = true)
  1899. {
  1900. $extra_data = array();
  1901. $table_user_field = Database::get_main_table(TABLE_MAIN_USER_FIELD);
  1902. $table_user_field_values = Database::get_main_table(TABLE_MAIN_USER_FIELD_VALUES);
  1903. $table_user_field_options = Database::get_main_table(TABLE_MAIN_USER_FIELD_OPTIONS);
  1904. $where = '';
  1905. /*
  1906. if (is_array($field_variable_array) && is_array($field_value_array)) {
  1907. if (count($field_variable_array) == count($field_value_array)) {
  1908. $field_var_count = count($field_variable_array);
  1909. for ($i = 0; $i < $field_var_count; $i++) {
  1910. if ($i != 0 && $i != $field_var_count) {
  1911. $where.= ' AND ';
  1912. }
  1913. $where.= "field_variable='".Database::escape_string($field_variable_array[$i])."' AND user_field_options.id='".Database::escape_string($field_value_array[$i])."'";
  1914. }
  1915. }
  1916. } */
  1917. $where = "field_variable='".Database::escape_string($field_variable)."' AND field_value='".Database::escape_string($field_value)."'";
  1918. $sql = "SELECT user_id FROM $table_user_field user_field INNER JOIN $table_user_field_values user_field_values
  1919. ON (user_field.id = user_field_values.field_id)
  1920. WHERE $where";
  1921. if ($all_visibility) {
  1922. $sql .= " AND user_field.field_visible = 1 ";
  1923. } else {
  1924. $sql .= " AND user_field.field_visible = 0 ";
  1925. }
  1926. $res = Database::query($sql);
  1927. $result_data = array();
  1928. if (Database::num_rows($res) > 0) {
  1929. while ($row = Database::fetch_array($res)) {
  1930. $result_data[] = $row['user_id'];
  1931. }
  1932. }
  1933. return $result_data;
  1934. }
  1935. /**
  1936. * Get extra user data by field variable
  1937. * @param string field variable
  1938. * @return array data
  1939. */
  1940. public static function get_extra_user_data_by_field_variable($field_variable)
  1941. {
  1942. $tbl_user_field_values = Database::get_main_table(TABLE_MAIN_USER_FIELD_VALUES);
  1943. $extra_information_by_variable = self::get_extra_field_information_by_name($field_variable);
  1944. $field_id = intval($extra_information_by_variable['id']);
  1945. $data = array();
  1946. $sql = "SELECT * FROM $tbl_user_field_values WHERE field_id='$field_id'";
  1947. $rs = Database::query($sql);
  1948. if (Database::num_rows($rs) > 0) {
  1949. while ($row = Database::fetch_array($rs)) {
  1950. $user_id = $row['user_id'];
  1951. $data[$user_id] = $row;
  1952. }
  1953. }
  1954. return $data;
  1955. }
  1956. /**
  1957. * Gives a list of [session_category][session_id] for the current user.
  1958. * @param integer $user_id
  1959. * @param boolean whether to fill the first element or not (to give space for courses out of categories)
  1960. * @param boolean optional true if limit time from session is over, false otherwise
  1961. * @return array list of statuses [session_category][session_id]
  1962. * @todo ensure multiple access urls are managed correctly
  1963. */
  1964. public static function get_sessions_by_category($user_id, $is_time_over = false, $ignore_visibility_for_admins = false)
  1965. {
  1966. // Database Table Definitions
  1967. $tbl_session = Database :: get_main_table(TABLE_MAIN_SESSION);
  1968. $tbl_session_course_user = Database :: get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
  1969. $tbl_session_category = Database :: get_main_table(TABLE_MAIN_SESSION_CATEGORY);
  1970. if ($user_id != strval(intval($user_id)))
  1971. return array();
  1972. $categories = array();
  1973. // Get the list of sessions per user
  1974. $now = api_get_utc_datetime();
  1975. if ($is_time_over) {
  1976. $condition_date_end = " AND (session.date_end < '$now' AND session.date_end != '0000-00-00') ";
  1977. } else {
  1978. if (api_is_allowed_to_create_course()) {
  1979. // Teachers can access the session depending in the access_coach date
  1980. $condition_date_end = null;
  1981. } else {
  1982. $condition_date_end = " AND (session.date_end >= '$now' OR session.date_end = '0000-00-00') ";
  1983. }
  1984. }
  1985. $sql = "SELECT DISTINCT
  1986. session.id,
  1987. session.name,
  1988. session.date_start,
  1989. session.date_end,
  1990. session_category_id,
  1991. session_category.name as session_category_name,
  1992. session_category.date_start session_category_date_start,
  1993. session_category.date_end session_category_date_end,
  1994. nb_days_access_before_beginning,
  1995. nb_days_access_after_end
  1996. FROM $tbl_session as session
  1997. LEFT JOIN $tbl_session_category session_category
  1998. ON (session_category_id = session_category.id)
  1999. INNER JOIN $tbl_session_course_user as session_rel_course_user
  2000. ON (session_rel_course_user.id_session = session.id)
  2001. WHERE (
  2002. session_rel_course_user.id_user = $user_id OR
  2003. session.id_coach = $user_id
  2004. ) $condition_date_end
  2005. ORDER BY session_category_name, name";
  2006. $result = Database::query($sql);
  2007. if (Database::num_rows($result) > 0) {
  2008. while ($row = Database::fetch_array($result)) {
  2009. $categories[$row['session_category_id']]['session_category']['id'] = $row['session_category_id'];
  2010. $categories[$row['session_category_id']]['session_category']['name'] = $row['session_category_name'];
  2011. $categories[$row['session_category_id']]['session_category']['date_start'] = $row['session_category_date_start'];
  2012. $categories[$row['session_category_id']]['session_category']['date_end'] = $row['session_category_date_end'];
  2013. $session_id = $row['id'];
  2014. // Checking session visibility
  2015. $visibility = api_get_session_visibility($session_id, null, $ignore_visibility_for_admins);
  2016. switch ($visibility) {
  2017. case SESSION_VISIBLE_READ_ONLY:
  2018. case SESSION_VISIBLE:
  2019. case SESSION_AVAILABLE:
  2020. break;
  2021. case SESSION_INVISIBLE:
  2022. continue(2);
  2023. }
  2024. $categories[$row['session_category_id']]['sessions'][$row['id']]['session_name'] = $row['name'];
  2025. $categories[$row['session_category_id']]['sessions'][$row['id']]['session_id'] = $row['id'];
  2026. $categories[$row['session_category_id']]['sessions'][$row['id']]['date_start'] = $row['date_start'];
  2027. $categories[$row['session_category_id']]['sessions'][$row['id']]['date_end'] = $row['date_end'];
  2028. $categories[$row['session_category_id']]['sessions'][$row['id']]['nb_days_access_before_beginning'] = $row['nb_days_access_before_beginning'];
  2029. $categories[$row['session_category_id']]['sessions'][$row['id']]['nb_days_access_after_end'] = $row['nb_days_access_after_end'];
  2030. $categories[$row['session_category_id']]['sessions'][$row['id']]['courses'] = UserManager::get_courses_list_by_session($user_id, $row['id']);
  2031. }
  2032. }
  2033. return $categories;
  2034. }
  2035. /**
  2036. * Gives a list of [session_id-course_code] => [status] for the current user.
  2037. * @param integer $user_id
  2038. * @return array list of statuses (session_id-course_code => status)
  2039. */
  2040. public static function get_personal_session_course_list($user_id)
  2041. {
  2042. // Database Table Definitions
  2043. $tbl_course = Database :: get_main_table(TABLE_MAIN_COURSE);
  2044. $tbl_user = Database :: get_main_table(TABLE_MAIN_USER);
  2045. $tbl_session = Database :: get_main_table(TABLE_MAIN_SESSION);
  2046. $tbl_session_user = Database :: get_main_table(TABLE_MAIN_SESSION_USER);
  2047. $tbl_course_user = Database :: get_main_table(TABLE_MAIN_COURSE_USER);
  2048. $tbl_session_course_user = Database :: get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
  2049. if ($user_id != strval(intval($user_id))) {
  2050. return array();
  2051. }
  2052. // We filter the courses from the URL
  2053. $join_access_url = $where_access_url = '';
  2054. if (api_get_multiple_access_url()) {
  2055. $access_url_id = api_get_current_access_url_id();
  2056. if ($access_url_id != -1) {
  2057. $tbl_url_course = Database :: get_main_table(TABLE_MAIN_ACCESS_URL_REL_COURSE);
  2058. $join_access_url = "LEFT JOIN $tbl_url_course url_rel_course ON url_rel_course.course_code= course.code";
  2059. $where_access_url = " AND access_url_id = $access_url_id ";
  2060. }
  2061. }
  2062. // Courses in which we subscribed out of any session
  2063. $tbl_user_course_category = Database :: get_user_personal_table(TABLE_USER_COURSE_CATEGORY);
  2064. $personal_course_list_sql = "SELECT
  2065. course.code,
  2066. course_rel_user.status course_rel_status,
  2067. course_rel_user.sort sort,
  2068. course_rel_user.user_course_cat user_course_cat
  2069. FROM ".$tbl_course_user." course_rel_user
  2070. LEFT JOIN ".$tbl_course." course
  2071. ON course.code = course_rel_user.course_code
  2072. LEFT JOIN ".$tbl_user_course_category." user_course_category
  2073. ON course_rel_user.user_course_cat = user_course_category.id
  2074. $join_access_url
  2075. WHERE course_rel_user.user_id = '".$user_id."' AND
  2076. course_rel_user.relation_type <> ".COURSE_RELATION_TYPE_RRHH."
  2077. $where_access_url
  2078. ORDER BY user_course_category.sort, course_rel_user.sort, course.title ASC";
  2079. $course_list_sql_result = Database::query($personal_course_list_sql);
  2080. $personal_course_list = array();
  2081. if (Database::num_rows($course_list_sql_result) > 0) {
  2082. while ($result_row = Database::fetch_array($course_list_sql_result, 'ASSOC')) {
  2083. $course_info = api_get_course_info($result_row['code']);
  2084. $result_row['course_info'] = $course_info;
  2085. $personal_course_list[] = $result_row;
  2086. }
  2087. }
  2088. $coachCourseConditions = null;
  2089. // Getting sessions that are related to a coach in the session_rel_course_rel_user table
  2090. if (api_is_allowed_to_create_course()) {
  2091. $sessionListFromCourseCoach = array();
  2092. $sql =" SELECT DISTINCT id_session FROM $tbl_session_course_user
  2093. WHERE id_user = $user_id AND status = 2 ";
  2094. $result = Database::query($sql);
  2095. if (Database::num_rows($result)) {
  2096. $result = Database::store_result($result);
  2097. foreach ($result as $session) {
  2098. $sessionListFromCourseCoach[]= $session['id_session'];
  2099. }
  2100. }
  2101. if (!empty($sessionListFromCourseCoach)) {
  2102. $condition = implode("','", $sessionListFromCourseCoach);
  2103. $coachCourseConditions = " OR ( id IN ('$condition'))";
  2104. }
  2105. }
  2106. // Get the list of sessions where the user is subscribed
  2107. // This is divided into two different queries
  2108. $sessions = array();
  2109. $sessions_sql = "SELECT DISTINCT id, name, date_start, date_end
  2110. FROM $tbl_session_user, $tbl_session
  2111. WHERE (
  2112. id_session = id AND
  2113. id_user = $user_id AND
  2114. relation_type <> ".SESSION_RELATION_TYPE_RRHH."
  2115. )
  2116. $coachCourseConditions
  2117. ORDER BY date_start, date_end, name";
  2118. $result = Database::query($sessions_sql);
  2119. if (Database::num_rows($result)>0) {
  2120. while ($row = Database::fetch_assoc($result)) {
  2121. $sessions[$row['id']] = $row;
  2122. }
  2123. }
  2124. $sessions_sql = "SELECT DISTINCT id, name, date_start, date_end
  2125. FROM $tbl_session_user, $tbl_session
  2126. WHERE (
  2127. id_coach = $user_id
  2128. )
  2129. $coachCourseConditions
  2130. ORDER BY date_start, date_end, name";
  2131. $result = Database::query($sessions_sql);
  2132. if (Database::num_rows($result)>0) {
  2133. while ($row = Database::fetch_assoc($result)) {
  2134. if (empty($sessions[$row['id']])) {
  2135. $sessions[$row['id']] = $row;
  2136. }
  2137. }
  2138. }
  2139. if (api_is_allowed_to_create_course()) {
  2140. foreach ($sessions as $enreg) {
  2141. $session_id = $enreg['id'];
  2142. $session_visibility = api_get_session_visibility($session_id);
  2143. if ($session_visibility == SESSION_INVISIBLE) {
  2144. continue;
  2145. }
  2146. $id_session = $enreg['id'];
  2147. $personal_course_list_sql = "SELECT DISTINCT
  2148. course.code code,
  2149. course.title i,
  2150. ".(api_is_western_name_order() ? "CONCAT(user.firstname,' ',user.lastname)" : "CONCAT(user.lastname,' ',user.firstname)")." t,
  2151. email, course.course_language l,
  2152. 1 sort,
  2153. category_code user_course_cat,
  2154. date_start,
  2155. date_end,
  2156. session.id as id_session,
  2157. session.name as session_name
  2158. FROM $tbl_session_course_user as session_course_user
  2159. INNER JOIN $tbl_course AS course
  2160. ON course.code = session_course_user.course_code
  2161. INNER JOIN $tbl_session as session
  2162. ON session.id = session_course_user.id_session
  2163. LEFT JOIN $tbl_user as user
  2164. ON user.user_id = session_course_user.id_user OR session.id_coach = user.user_id
  2165. WHERE
  2166. session_course_user.id_session = $id_session AND (
  2167. (session_course_user.id_user = $user_id AND session_course_user.status = 2)
  2168. OR session.id_coach = $user_id
  2169. )
  2170. ORDER BY i";
  2171. $course_list_sql_result = Database::query($personal_course_list_sql);
  2172. while ($result_row = Database::fetch_array($course_list_sql_result, 'ASSOC')) {
  2173. $result_row['course_info'] = api_get_course_info($result_row['code']);
  2174. $key = $result_row['id_session'].' - '.$result_row['code'];
  2175. $personal_course_list[$key] = $result_row;
  2176. }
  2177. }
  2178. }
  2179. foreach ($sessions as $enreg) {
  2180. $session_id = $enreg['id'];
  2181. $session_visibility = api_get_session_visibility($session_id);
  2182. if ($session_visibility == SESSION_INVISIBLE) {
  2183. continue;
  2184. }
  2185. /* This query is very similar to the above query,
  2186. but it will check the session_rel_course_user table if there are courses registered to our user or not */
  2187. $personal_course_list_sql = "SELECT DISTINCT
  2188. course.code code,
  2189. course.title i, CONCAT(user.lastname,' ',user.firstname) t,
  2190. email,
  2191. course.course_language l,
  2192. 1 sort,
  2193. category_code user_course_cat,
  2194. date_start,
  2195. date_end,
  2196. session.id as id_session,
  2197. session.name as session_name,
  2198. IF((session_course_user.id_user = 3 AND session_course_user.status=2),'2', '5')
  2199. FROM $tbl_session_course_user as session_course_user
  2200. INNER JOIN $tbl_course AS course
  2201. ON course.code = session_course_user.course_code AND session_course_user.id_session = $session_id
  2202. INNER JOIN $tbl_session as session ON session_course_user.id_session = session.id
  2203. LEFT JOIN $tbl_user as user ON user.user_id = session_course_user.id_user
  2204. WHERE session_course_user.id_user = $user_id
  2205. ORDER BY i";
  2206. $course_list_sql_result = Database::query($personal_course_list_sql);
  2207. while ($result_row = Database::fetch_array($course_list_sql_result, 'ASSOC')) {
  2208. $result_row['course_info'] = api_get_course_info($result_row['code']);
  2209. $key = $result_row['id_session'].' - '.$result_row['code'];
  2210. if (!isset($personal_course_list[$key])) {
  2211. $personal_course_list[$key] = $result_row;
  2212. }
  2213. }
  2214. }
  2215. return $personal_course_list;
  2216. }
  2217. /**
  2218. * Gives a list of courses for the given user in the given session
  2219. * @param integer $user_id
  2220. * @param integer $session_id
  2221. * @return array list of statuses (session_id-course_code => status)
  2222. */
  2223. public static function get_courses_list_by_session($user_id, $session_id)
  2224. {
  2225. // Database Table Definitions
  2226. $tbl_session = Database :: get_main_table(TABLE_MAIN_SESSION);
  2227. $tbl_session_course_user = Database :: get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
  2228. $tbl_session_course = Database :: get_main_table(TABLE_MAIN_SESSION_COURSE);
  2229. $user_id = intval($user_id);
  2230. $session_id = intval($session_id);
  2231. //we filter the courses from the URL
  2232. $join_access_url = $where_access_url = '';
  2233. if (api_get_multiple_access_url()) {
  2234. $access_url_id = api_get_current_access_url_id();
  2235. if ($access_url_id != -1) {
  2236. $tbl_url_session = Database :: get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
  2237. $join_access_url = " , $tbl_url_session url_rel_session ";
  2238. $where_access_url = " AND access_url_id = $access_url_id AND url_rel_session.session_id = $session_id ";
  2239. }
  2240. }
  2241. $personal_course_list = array();
  2242. $courses = array();
  2243. /* This query is very similar to the above query,but it will check the
  2244. session_rel_course_user table if there are courses registered
  2245. to our user or not*/
  2246. $sql = "SELECT DISTINCT scu.course_code as code
  2247. FROM $tbl_session_course_user as scu
  2248. INNER JOIN $tbl_session_course sc
  2249. ON (scu.id_session = sc.id_session AND scu.course_code = sc.course_code)
  2250. $join_access_url
  2251. WHERE scu.id_user = $user_id AND scu.id_session = $session_id $where_access_url
  2252. ORDER BY code";
  2253. $result = Database::query($sql);
  2254. if (Database::num_rows($result) > 0) {
  2255. while ($result_row = Database::fetch_array($result)) {
  2256. $result_row['status'] = 5;
  2257. if (!in_array($result_row['code'], $courses)) {
  2258. $personal_course_list[] = $result_row;
  2259. $courses[] = $result_row['code'];
  2260. }
  2261. }
  2262. }
  2263. if (api_is_allowed_to_create_course()) {
  2264. $sql = "SELECT DISTINCT scu.course_code as code
  2265. FROM $tbl_session_course_user as scu
  2266. INNER JOIN $tbl_session as s
  2267. ON (scu.id_session = s.id)
  2268. INNER JOIN $tbl_session_course sc
  2269. ON (scu.id_session = sc.id_session AND scu.course_code = sc.course_code)
  2270. $join_access_url
  2271. WHERE
  2272. s.id = $session_id AND
  2273. (
  2274. (scu.id_user=$user_id AND scu.status=2) OR
  2275. s.id_coach = $user_id
  2276. )
  2277. $where_access_url
  2278. ORDER BY code";
  2279. $result = Database::query($sql);
  2280. if (Database::num_rows($result) > 0) {
  2281. while ($result_row = Database::fetch_array($result)) {
  2282. $result_row['status'] = 2;
  2283. if (!in_array($result_row['code'], $courses)) {
  2284. $personal_course_list[] = $result_row;
  2285. $courses[] = $result_row['code'];
  2286. }
  2287. }
  2288. }
  2289. }
  2290. $course_list = array();
  2291. if (api_is_drh()) {
  2292. $session_list = SessionManager::get_sessions_followed_by_drh($user_id);
  2293. $session_list = array_keys($session_list);
  2294. if (in_array($session_id, $session_list)) {
  2295. $course_list = SessionManager::get_course_list_by_session_id($session_id);
  2296. if (!empty($course_list)) {
  2297. foreach ($course_list as $course) {
  2298. $personal_course_list[] = $course;
  2299. }
  2300. }
  2301. }
  2302. } else {
  2303. //check if user is general coach for this session
  2304. $s = api_get_session_info($session_id);
  2305. if ($s['id_coach'] == $user_id) {
  2306. $course_list = SessionManager::get_course_list_by_session_id($session_id);
  2307. if (!empty($course_list)) {
  2308. foreach ($course_list as $course) {
  2309. if (!in_array($course['code'],$courses)) {
  2310. $personal_course_list[] = $course;
  2311. }
  2312. }
  2313. }
  2314. }
  2315. }
  2316. return $personal_course_list;
  2317. }
  2318. /**
  2319. * Get user id from a username
  2320. * @param string Username
  2321. * @return int User ID (or false if not found)
  2322. */
  2323. public static function get_user_id_from_username($username)
  2324. {
  2325. if (empty($username)) {
  2326. return false;
  2327. }
  2328. $username = trim($username);
  2329. $username = Database::escape_string($username);
  2330. $t_user = Database::get_main_table(TABLE_MAIN_USER);
  2331. $sql = "SELECT user_id FROM $t_user WHERE username = '$username'";
  2332. $res = Database::query($sql);
  2333. if ($res === false) {
  2334. return false;
  2335. }
  2336. if (Database::num_rows($res) !== 1) {
  2337. return false;
  2338. }
  2339. $row = Database::fetch_array($res);
  2340. return $row['user_id'];
  2341. }
  2342. /**
  2343. * Get the users files upload from his share_folder
  2344. * @param string User ID
  2345. * @param string course directory
  2346. * @param string resourcetype: images, all
  2347. * @return int User ID (or false if not found)
  2348. */
  2349. public static function get_user_upload_files_by_course($user_id, $course, $resourcetype = 'all')
  2350. {
  2351. $return = '';
  2352. if (!empty($user_id) && !empty($course)) {
  2353. $user_id = intval($user_id);
  2354. $path = api_get_path(SYS_COURSE_PATH).$course.'/document/shared_folder/sf_user_'.$user_id.'/';
  2355. $web_path = api_get_path(WEB_COURSE_PATH).$course.'/document/shared_folder/sf_user_'.$user_id.'/';
  2356. $file_list = array();
  2357. if (is_dir($path)) {
  2358. $handle = opendir($path);
  2359. while ($file = readdir($handle)) {
  2360. if ($file == '.' || $file == '..' || $file == '.htaccess' || is_dir($path.$file)) {
  2361. continue; // skip current/parent directory and .htaccess
  2362. }
  2363. $file_list[] = $file;
  2364. }
  2365. if (count($file_list) > 0) {
  2366. $return = "<h4>$course</h4>";
  2367. $return .= '<ul class="thumbnails">';
  2368. }
  2369. foreach ($file_list as $file) {
  2370. if ($resourcetype == "all") {
  2371. $return .= '<li><a href="'.$web_path.urlencode($file).'" target="_blank">'.htmlentities($file).'</a></li>';
  2372. } elseif ($resourcetype == "images") {
  2373. //get extension
  2374. $ext = explode('.', $file);
  2375. if ($ext[1] == 'jpg' || $ext[1] == 'jpeg' || $ext[1] == 'png' || $ext[1] == 'gif' || $ext[1] == 'bmp' || $ext[1] == 'tif') {
  2376. $return .= '<li class="span2"><a class="thumbnail" href="'.$web_path.urlencode($file).'" target="_blank">
  2377. <img src="'.$web_path.urlencode($file).'" ></a>
  2378. </li>';
  2379. }
  2380. }
  2381. }
  2382. if (count($file_list) > 0) {
  2383. $return .= '</ul>';
  2384. }
  2385. }
  2386. }
  2387. return $return;
  2388. }
  2389. /**
  2390. * Gets the API key (or keys) and return them into an array
  2391. * @param int Optional user id (defaults to the result of api_get_user_id())
  2392. * @return array Non-indexed array containing the list of API keys for this user, or FALSE on error
  2393. */
  2394. public static function get_api_keys($user_id = null, $api_service = 'dokeos')
  2395. {
  2396. if ($user_id != strval(intval($user_id)))
  2397. return false;
  2398. if (empty($user_id)) {
  2399. $user_id = api_get_user_id();
  2400. }
  2401. if ($user_id === false)
  2402. return false;
  2403. $service_name = Database::escape_string($api_service);
  2404. if (is_string($service_name) === false) {
  2405. return false;
  2406. }
  2407. $t_api = Database::get_main_table(TABLE_MAIN_USER_API_KEY);
  2408. $sql = "SELECT * FROM $t_api WHERE user_id = $user_id AND api_service='$api_service';";
  2409. $res = Database::query($sql);
  2410. if ($res === false)
  2411. return false; //error during query
  2412. $num = Database::num_rows($res);
  2413. if ($num == 0)
  2414. return false;
  2415. $list = array();
  2416. while ($row = Database::fetch_array($res)) {
  2417. $list[$row['id']] = $row['api_key'];
  2418. }
  2419. return $list;
  2420. }
  2421. /**
  2422. * Adds a new API key to the users' account
  2423. * @param int Optional user ID (defaults to the results of api_get_user_id())
  2424. * @return boolean True on success, false on failure
  2425. */
  2426. public static function add_api_key($user_id = null, $api_service = 'dokeos')
  2427. {
  2428. if ($user_id != strval(intval($user_id)))
  2429. return false;
  2430. if (empty($user_id)) {
  2431. $user_id = api_get_user_id();
  2432. }
  2433. if ($user_id === false)
  2434. return false;
  2435. $service_name = Database::escape_string($api_service);
  2436. if (is_string($service_name) === false) {
  2437. return false;
  2438. }
  2439. $t_api = Database::get_main_table(TABLE_MAIN_USER_API_KEY);
  2440. $md5 = md5((time() + ($user_id * 5)) - rand(10000, 10000)); //generate some kind of random key
  2441. $sql = "INSERT INTO $t_api (user_id, api_key,api_service) VALUES ($user_id,'$md5','$service_name')";
  2442. $res = Database::query($sql);
  2443. if ($res === false)
  2444. return false; //error during query
  2445. $num = Database::insert_id();
  2446. return ($num == 0) ? false : $num;
  2447. }
  2448. /**
  2449. * Deletes an API key from the user's account
  2450. * @param int API key's internal ID
  2451. * @return boolean True on success, false on failure
  2452. */
  2453. public static function delete_api_key($key_id)
  2454. {
  2455. if ($key_id != strval(intval($key_id)))
  2456. return false;
  2457. if ($key_id === false)
  2458. return false;
  2459. $t_api = Database::get_main_table(TABLE_MAIN_USER_API_KEY);
  2460. $sql = "SELECT * FROM $t_api WHERE id = ".$key_id;
  2461. $res = Database::query($sql);
  2462. if ($res === false)
  2463. return false; //error during query
  2464. $num = Database::num_rows($res);
  2465. if ($num !== 1)
  2466. return false;
  2467. $sql = "DELETE FROM $t_api WHERE id = ".$key_id;
  2468. $res = Database::query($sql);
  2469. if ($res === false)
  2470. return false; //error during query
  2471. return true;
  2472. }
  2473. /**
  2474. * Regenerate an API key from the user's account
  2475. * @param int user ID (defaults to the results of api_get_user_id())
  2476. * @param string API key's internal ID
  2477. * @return int num
  2478. */
  2479. public static function update_api_key($user_id, $api_service)
  2480. {
  2481. if ($user_id != strval(intval($user_id)))
  2482. return false;
  2483. if ($user_id === false)
  2484. return false;
  2485. $service_name = Database::escape_string($api_service);
  2486. if (is_string($service_name) === false) {
  2487. return false;
  2488. }
  2489. $t_api = Database::get_main_table(TABLE_MAIN_USER_API_KEY);
  2490. $sql = "SELECT id FROM $t_api WHERE user_id=".$user_id." AND api_service='".$api_service."'";
  2491. $res = Database::query($sql);
  2492. $num = Database::num_rows($res);
  2493. if ($num == 1) {
  2494. $id_key = Database::fetch_array($res, 'ASSOC');
  2495. self::delete_api_key($id_key['id']);
  2496. $num = self::add_api_key($user_id, $api_service);
  2497. } elseif ($num == 0) {
  2498. $num = self::add_api_key($user_id);
  2499. }
  2500. return $num;
  2501. }
  2502. /**
  2503. * @param int user ID (defaults to the results of api_get_user_id())
  2504. * @param string API key's internal ID
  2505. * @return int row ID, or return false if not found
  2506. */
  2507. public static function get_api_key_id($user_id, $api_service)
  2508. {
  2509. if ($user_id != strval(intval($user_id)))
  2510. return false;
  2511. if ($user_id === false)
  2512. return false;
  2513. if (empty($api_service))
  2514. return false;
  2515. $t_api = Database::get_main_table(TABLE_MAIN_USER_API_KEY);
  2516. $service_name = Database::escape_string($api_service);
  2517. $sql = "SELECT id FROM $t_api WHERE user_id=".$user_id." AND api_service='".$api_service."'";
  2518. $res = Database::query($sql);
  2519. if (Database::num_rows($res) < 1) {
  2520. return false;
  2521. }
  2522. $row = Database::fetch_array($res, 'ASSOC');
  2523. return $row['id'];
  2524. }
  2525. /**
  2526. * Checks if a user_id is platform admin
  2527. * @param int user ID
  2528. * @return boolean True if is admin, false otherwise
  2529. * @see main_api.lib.php::api_is_platform_admin() for a context-based check
  2530. */
  2531. public static function is_admin($user_id)
  2532. {
  2533. if (empty($user_id) or $user_id != strval(intval($user_id))) {
  2534. return false;
  2535. }
  2536. $admin_table = Database::get_main_table(TABLE_MAIN_ADMIN);
  2537. $sql = "SELECT * FROM $admin_table WHERE user_id = $user_id";
  2538. $res = Database::query($sql);
  2539. return Database::num_rows($res) === 1;
  2540. }
  2541. /**
  2542. * Get the total count of users
  2543. * @param int Status of users to be counted
  2544. * @param int Access URL ID (optional)
  2545. * @return mixed Number of users or false on error
  2546. */
  2547. public static function get_number_of_users($status = 0, $access_url_id = null)
  2548. {
  2549. $t_u = Database::get_main_table(TABLE_MAIN_USER);
  2550. $t_a = Database :: get_main_table(TABLE_MAIN_ACCESS_URL_REL_USER);
  2551. $sql = "SELECT count(*) FROM $t_u u";
  2552. $sql2 = '';
  2553. if (is_int($status) && $status > 0) {
  2554. $sql2 .= " WHERE u.status = $status ";
  2555. }
  2556. if (!empty($access_url_id) && $access_url_id == intval($access_url_id)) {
  2557. $sql .= ", $t_a a ";
  2558. $sql2 .= " AND a.access_url_id = $access_url_id AND u.user_id = a.user_id ";
  2559. }
  2560. $sql = $sql.$sql2;
  2561. $res = Database::query($sql);
  2562. if (Database::num_rows($res) === 1) {
  2563. return (int) Database::result($res, 0, 0);
  2564. }
  2565. return false;
  2566. }
  2567. /**
  2568. * Resize a picture
  2569. *
  2570. * @param string file picture
  2571. * @param int size in pixels
  2572. * @todo move this function somewhere else image.lib?
  2573. * @return obj image object
  2574. */
  2575. public static function resize_picture($file, $max_size_for_picture)
  2576. {
  2577. $temp = false;
  2578. if (file_exists($file)) {
  2579. $temp = new Image($file);
  2580. $image_size = $temp->get_image_size($file);
  2581. $width = $image_size['width'];
  2582. $height = $image_size['height'];
  2583. if ($width >= $height) {
  2584. if ($width >= $max_size_for_picture) {
  2585. // scale height
  2586. $new_height = round($height * ($max_size_for_picture / $width));
  2587. $temp->resize($max_size_for_picture, $new_height, 0);
  2588. }
  2589. } else { // height > $width
  2590. if ($height >= $max_size_for_picture) {
  2591. // scale width
  2592. $new_width = round($width * ($max_size_for_picture / $height));
  2593. $temp->resize($new_width, $max_size_for_picture, 0);
  2594. }
  2595. }
  2596. }
  2597. return $temp;
  2598. }
  2599. /**
  2600. * Gets the current user image
  2601. * @param string user id
  2602. * @param string picture user name
  2603. * @param string height
  2604. * @param string picture size it can be USER_IMAGE_SIZE_SMALL, USER_IMAGE_SIZE_MEDIUM, USER_IMAGE_SIZE_BIG or USER_IMAGE_SIZE_ORIGINAL
  2605. * @param string style css
  2606. * @return array with the file and the style of an image i.e $array['file'] $array['style']
  2607. */
  2608. public static function get_picture_user($user_id, $picture_file, $height, $size_picture = USER_IMAGE_SIZE_MEDIUM, $style = '')
  2609. {
  2610. $picture = array();
  2611. $picture['style'] = $style;
  2612. if ($picture_file == 'unknown.jpg') {
  2613. $picture['file'] = api_get_path(WEB_CODE_PATH).'img/'.$picture_file;
  2614. return $picture;
  2615. }
  2616. switch ($size_picture) {
  2617. case USER_IMAGE_SIZE_ORIGINAL :
  2618. $size_picture = '';
  2619. break;
  2620. case USER_IMAGE_SIZE_BIG :
  2621. $size_picture = 'big_';
  2622. break;
  2623. case USER_IMAGE_SIZE_MEDIUM :
  2624. $size_picture = 'medium_';
  2625. break;
  2626. case USER_IMAGE_SIZE_SMALL :
  2627. $size_picture = 'small_';
  2628. break;
  2629. default:
  2630. $size_picture = 'medium_';
  2631. }
  2632. $image_array_sys = self::get_user_picture_path_by_id($user_id, 'system', false, true);
  2633. $image_array = self::get_user_picture_path_by_id($user_id, 'web', false, true);
  2634. $file = $image_array_sys['dir'].$size_picture.$picture_file;
  2635. if (file_exists($file)) {
  2636. $picture['file'] = $image_array['dir'].$size_picture.$picture_file;
  2637. $picture['style'] = '';
  2638. if ($height > 0) {
  2639. $dimension = api_getimagesize($picture['file']);
  2640. $margin = (($height - $dimension['width']) / 2);
  2641. //@ todo the padding-top should not be here
  2642. $picture['style'] = ' style="padding-top:'.$margin.'px; width:'.$dimension['width'].'px; height:'.$dimension['height'].'px;" ';
  2643. $picture['original_height'] = $dimension['width'];
  2644. $picture['original_width'] = $dimension['height'];
  2645. }
  2646. } else {
  2647. $file = $image_array_sys['dir'].$picture_file;
  2648. if (file_exists($file) && !is_dir($file)) {
  2649. $picture['file'] = $image_array['dir'].$picture_file;
  2650. } else {
  2651. switch ($size_picture) {
  2652. case 'big_' :
  2653. $picture['file'] = api_get_path(WEB_CODE_PATH).'img/unknown.jpg';
  2654. break;
  2655. case 'medium_' :
  2656. $picture['file'] = api_get_path(WEB_CODE_PATH).'img/unknown_50_50.jpg';
  2657. break;
  2658. case 'small_' :
  2659. $picture['file'] = api_get_path(WEB_CODE_PATH).'img/unknown.jpg';
  2660. break;
  2661. default:
  2662. $picture['file'] = api_get_path(WEB_CODE_PATH).'img/unknown.jpg';
  2663. break;
  2664. }
  2665. }
  2666. }
  2667. return $picture;
  2668. }
  2669. /**
  2670. * @author Isaac flores <isaac.flores@dokeos.com>
  2671. * @param string The email administrator
  2672. * @param integer The user id
  2673. * @param string The message title
  2674. * @param string The content message
  2675. */
  2676. public static function send_message_in_outbox($email_administrator, $user_id, $title, $content)
  2677. {
  2678. $table_message = Database::get_main_table(TABLE_MESSAGE);
  2679. $table_user = Database::get_main_table(TABLE_MAIN_USER);
  2680. $title = api_utf8_decode($title);
  2681. $content = api_utf8_decode($content);
  2682. $email_administrator = Database::escape_string($email_administrator);
  2683. //message in inbox
  2684. $sql_message_outbox = 'SELECT user_id from '.$table_user.' WHERE email="'.$email_administrator.'" ';
  2685. //$num_row_query = Database::num_rows($sql_message_outbox);
  2686. $res_message_outbox = Database::query($sql_message_outbox);
  2687. $array_users_administrator = array();
  2688. while ($row_message_outbox = Database::fetch_array($res_message_outbox, 'ASSOC')) {
  2689. $array_users_administrator[] = $row_message_outbox['user_id'];
  2690. }
  2691. //allow to insert messages in outbox
  2692. for ($i = 0; $i < count($array_users_administrator); $i++) {
  2693. $sql_insert_outbox = "INSERT INTO $table_message(user_sender_id, user_receiver_id, msg_status, send_date, title, content ) ".
  2694. " VALUES (".
  2695. "'".(int) $user_id."', '".(int) ($array_users_administrator[$i])."', '4', '".date('Y-m-d H:i:s')."','".Database::escape_string($title)."','".Database::escape_string($content)."'".
  2696. ")";
  2697. $rs = Database::query($sql_insert_outbox);
  2698. }
  2699. }
  2700. /*
  2701. *
  2702. * USER TAGS
  2703. *
  2704. * Intructions to create a new user tag by Julio Montoya <gugli100@gmail.com>
  2705. *
  2706. * 1. Create a new extra field in main/admin/user_fields.php with the "TAG" field type make it available and visible. Called it "books" for example.
  2707. * 2. Go to profile main/auth/profile.php There you will see a special input (facebook style) that will show suggestions of tags.
  2708. * 3. All the tags are registered in the user_tag table and the relationship between user and tags is in the user_rel_tag table
  2709. * 4. Tags are independent this means that tags can't be shared between tags + book + hobbies.
  2710. * 5. Test and enjoy.
  2711. *
  2712. */
  2713. /**
  2714. * Gets the tags of a specific field_id
  2715. *
  2716. * @param int field_id
  2717. * @param string how we are going to result value in array or in a string (json)
  2718. * @return mixed
  2719. * @since Nov 2009
  2720. * @version 1.8.6.2
  2721. */
  2722. public static function get_tags($tag, $field_id, $return_format = 'json', $limit = 10)
  2723. {
  2724. // database table definition
  2725. $table_user_tag = Database::get_main_table(TABLE_MAIN_TAG);
  2726. $field_id = intval($field_id);
  2727. $limit = intval($limit);
  2728. $tag = trim(Database::escape_string($tag));
  2729. // all the information of the field
  2730. $sql = "SELECT DISTINCT id, tag from $table_user_tag
  2731. WHERE field_id = $field_id AND tag LIKE '$tag%' ORDER BY tag LIMIT $limit";
  2732. $result = Database::query($sql);
  2733. $return = array();
  2734. if (Database::num_rows($result) > 0) {
  2735. while ($row = Database::fetch_array($result, 'ASSOC')) {
  2736. $return[] = array('caption' => $row['tag'], 'value' => $row['tag']);
  2737. }
  2738. }
  2739. if ($return_format == 'json') {
  2740. $return = json_encode($return);
  2741. }
  2742. return $return;
  2743. }
  2744. /**
  2745. * @param int $field_id
  2746. * @param int $limit
  2747. * @return array
  2748. */
  2749. public static function get_top_tags($field_id, $limit = 100)
  2750. {
  2751. // database table definition
  2752. $table_user_tag = Database::get_main_table(TABLE_MAIN_TAG);
  2753. $table_user_tag_values = Database::get_main_table(TABLE_MAIN_USER_REL_TAG);
  2754. $field_id = intval($field_id);
  2755. $limit = intval($limit);
  2756. // all the information of the field
  2757. $sql = "SELECT count(*) count, tag FROM $table_user_tag_values uv INNER JOIN $table_user_tag ut ON(ut.id = uv.tag_id)
  2758. WHERE field_id = $field_id GROUP BY tag_id ORDER BY count DESC LIMIT $limit";
  2759. $result = Database::query($sql);
  2760. $return = array();
  2761. if (Database::num_rows($result) > 0) {
  2762. while ($row = Database::fetch_array($result, 'ASSOC')) {
  2763. $return[] = $row;
  2764. }
  2765. }
  2766. return $return;
  2767. }
  2768. /**
  2769. * Get user's tags
  2770. * @param int field_id
  2771. * @param int user_id
  2772. * @return array
  2773. */
  2774. public static function get_user_tags($user_id, $field_id)
  2775. {
  2776. // database table definition
  2777. $table_user_tag = Database::get_main_table(TABLE_MAIN_TAG);
  2778. $table_user_tag_values = Database::get_main_table(TABLE_MAIN_USER_REL_TAG);
  2779. $field_id = intval($field_id);
  2780. $user_id = intval($user_id);
  2781. // all the information of the field
  2782. $sql = "SELECT ut.id, tag,count FROM $table_user_tag ut INNER JOIN $table_user_tag_values uv ON (uv.tag_id=ut.ID)
  2783. WHERE field_id = $field_id AND user_id = $user_id ORDER BY tag";
  2784. $result = Database::query($sql);
  2785. $return = array();
  2786. if (Database::num_rows($result) > 0) {
  2787. while ($row = Database::fetch_array($result, 'ASSOC')) {
  2788. $return[$row['id']] = array('tag' => $row['tag'], 'count' => $row['count']);
  2789. }
  2790. }
  2791. return $return;
  2792. }
  2793. /**
  2794. * Get user's tags
  2795. * @param int user_id
  2796. * @param int field_id
  2797. * @param bool show links or not
  2798. * @return array
  2799. */
  2800. public static function get_user_tags_to_string($user_id, $field_id, $show_links = true)
  2801. {
  2802. // database table definition
  2803. $table_user_tag = Database::get_main_table(TABLE_MAIN_TAG);
  2804. $table_user_tag_values = Database::get_main_table(TABLE_MAIN_USER_REL_TAG);
  2805. $field_id = intval($field_id);
  2806. $user_id = intval($user_id);
  2807. // all the information of the field
  2808. $sql = "SELECT ut.id, tag,count FROM $table_user_tag ut INNER JOIN $table_user_tag_values uv ON (uv.tag_id=ut.ID)
  2809. WHERE field_id = $field_id AND user_id = $user_id ORDER BY tag";
  2810. $result = Database::query($sql);
  2811. $return = array();
  2812. if (Database::num_rows($result) > 0) {
  2813. while ($row = Database::fetch_array($result, 'ASSOC')) {
  2814. $return[$row['id']] = array('tag' => $row['tag'], 'count' => $row['count']);
  2815. }
  2816. }
  2817. $user_tags = $return;
  2818. $tag_tmp = array();
  2819. foreach ($user_tags as $tag) {
  2820. if ($show_links) {
  2821. $tag_tmp[] = '<a href="'.api_get_path(WEB_PATH).'main/search/index.php?q='.$tag['tag'].'">'.$tag['tag'].'</a>';
  2822. } else {
  2823. $tag_tmp[] = $tag['tag'];
  2824. }
  2825. }
  2826. if (is_array($user_tags) && count($user_tags) > 0) {
  2827. $return = implode(', ', $tag_tmp);
  2828. } else {
  2829. return '';
  2830. }
  2831. return $return;
  2832. }
  2833. /**
  2834. * Get the tag id
  2835. * @param int tag
  2836. * @param int field_id
  2837. * @return int returns 0 if fails otherwise the tag id
  2838. */
  2839. public static function get_tag_id($tag, $field_id)
  2840. {
  2841. $table_user_tag = Database::get_main_table(TABLE_MAIN_TAG);
  2842. $tag = Database::escape_string($tag);
  2843. $field_id = intval($field_id);
  2844. //with COLLATE latin1_bin to select query in a case sensitive mode
  2845. $sql = "SELECT id FROM $table_user_tag WHERE tag LIKE '$tag' AND field_id = $field_id";
  2846. $result = Database::query($sql);
  2847. if (Database::num_rows($result) > 0) {
  2848. $row = Database::fetch_array($result, 'ASSOC');
  2849. return $row['id'];
  2850. } else {
  2851. return 0;
  2852. }
  2853. }
  2854. /**
  2855. * Get the tag id
  2856. * @param int tag
  2857. * @param int field_id
  2858. * @return int 0 if fails otherwise the tag id
  2859. */
  2860. public static function get_tag_id_from_id($tag_id, $field_id)
  2861. {
  2862. $table_user_tag = Database::get_main_table(TABLE_MAIN_TAG);
  2863. $tag_id = intval($tag_id);
  2864. $field_id = intval($field_id);
  2865. $sql = "SELECT id FROM $table_user_tag WHERE id = '$tag_id' AND field_id = $field_id";
  2866. $result = Database::query($sql);
  2867. if (Database::num_rows($result) > 0) {
  2868. $row = Database::fetch_array($result, 'ASSOC');
  2869. return $row['id'];
  2870. } else {
  2871. return false;
  2872. }
  2873. }
  2874. /**
  2875. * Adds a user-tag value
  2876. * @param mixed tag
  2877. * @param int The user id
  2878. * @param int field id of the tag
  2879. * @return bool
  2880. */
  2881. public static function add_tag($tag, $user_id, $field_id)
  2882. {
  2883. // database table definition
  2884. $table_user_tag = Database::get_main_table(TABLE_MAIN_TAG);
  2885. $table_user_tag_values = Database::get_main_table(TABLE_MAIN_USER_REL_TAG);
  2886. $tag = trim(Database::escape_string($tag));
  2887. $user_id = intval($user_id);
  2888. $field_id = intval($field_id);
  2889. $tag_id = UserManager::get_tag_id($tag, $field_id);
  2890. /* IMPORTANT
  2891. * @todo we don't create tags with numbers
  2892. *
  2893. */
  2894. if (is_numeric($tag)) {
  2895. //the form is sending an id this means that the user select it from the list so it MUST exists
  2896. /* $new_tag_id = UserManager::get_tag_id_from_id($tag,$field_id);
  2897. if ($new_tag_id !== false) {
  2898. $sql = "UPDATE $table_user_tag SET count = count + 1 WHERE id = $new_tag_id";
  2899. $result = Database::query($sql);
  2900. $last_insert_id = $new_tag_id;
  2901. } else {
  2902. $sql = "INSERT INTO $table_user_tag (tag, field_id,count) VALUES ('$tag','$field_id', count + 1)";
  2903. $result = Database::query($sql);
  2904. $last_insert_id = Database::get_last_insert_id();
  2905. } */
  2906. } else {
  2907. }
  2908. //this is a new tag
  2909. if ($tag_id == 0) {
  2910. //the tag doesn't exist
  2911. $sql = "INSERT INTO $table_user_tag (tag, field_id,count) VALUES ('$tag','$field_id', count + 1)";
  2912. $result = Database::query($sql);
  2913. $last_insert_id = Database::get_last_insert_id();
  2914. } else {
  2915. //the tag exists we update it
  2916. $sql = "UPDATE $table_user_tag SET count = count + 1 WHERE id = $tag_id";
  2917. $result = Database::query($sql);
  2918. $last_insert_id = $tag_id;
  2919. }
  2920. if (!empty($last_insert_id) && ($last_insert_id != 0)) {
  2921. //we insert the relationship user-tag
  2922. $sql_select = "SELECT tag_id FROM $table_user_tag_values WHERE user_id = $user_id AND tag_id = $last_insert_id ";
  2923. $result = Database::query($sql_select);
  2924. //if the relationship does not exist we create it
  2925. if (Database::num_rows($result) == 0) {
  2926. $sql = "INSERT INTO $table_user_tag_values SET user_id = $user_id, tag_id = $last_insert_id";
  2927. $result = Database::query($sql);
  2928. }
  2929. }
  2930. }
  2931. /**
  2932. * Deletes an user tag
  2933. * @param int user id
  2934. * @param int field id
  2935. *
  2936. */
  2937. public static function delete_user_tags($user_id, $field_id)
  2938. {
  2939. // database table definition
  2940. $table_user_tag = Database::get_main_table(TABLE_MAIN_TAG);
  2941. $table_user_tag_values = Database::get_main_table(TABLE_MAIN_USER_REL_TAG);
  2942. $tags = UserManager::get_user_tags($user_id, $field_id);
  2943. if (is_array($tags) && count($tags) > 0) {
  2944. foreach ($tags as $key => $tag) {
  2945. if ($tag['count'] > '0') {
  2946. $sql = "UPDATE $table_user_tag SET count = count - 1 WHERE id = $key ";
  2947. Database::query($sql);
  2948. }
  2949. $sql = "DELETE FROM $table_user_tag_values WHERE user_id = $user_id AND tag_id = $key";
  2950. Database::query($sql);
  2951. }
  2952. }
  2953. }
  2954. /**
  2955. * Process the tag list comes from the UserManager::update_extra_field_value() function
  2956. * @param array the tag list that will be added
  2957. * @param int user id
  2958. * @param int field id
  2959. * @return bool
  2960. */
  2961. public static function process_tags($tags, $user_id, $field_id)
  2962. {
  2963. //We loop the tags and add it to the DB
  2964. if (is_array($tags)) {
  2965. foreach ($tags as $tag) {
  2966. UserManager::add_tag($tag, $user_id, $field_id);
  2967. }
  2968. } else {
  2969. UserManager::add_tag($tags, $user_id, $field_id);
  2970. }
  2971. return true;
  2972. }
  2973. /**
  2974. * Returns a list of all admninistrators
  2975. * @author jmontoya
  2976. * @return array
  2977. */
  2978. public static function get_all_administrators()
  2979. {
  2980. $table_user = Database::get_main_table(TABLE_MAIN_USER);
  2981. $table_admin = Database::get_main_table(TABLE_MAIN_ADMIN);
  2982. $tbl_url_rel_user = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_USER);
  2983. $access_url_id = api_get_current_access_url_id();
  2984. if (api_get_multiple_access_url()) {
  2985. $access_url_id = api_get_current_access_url_id();
  2986. $sql = "SELECT admin.user_id, username, firstname, lastname, email FROM $tbl_url_rel_user as url INNER JOIN $table_admin as admin
  2987. ON (admin.user_id=url.user_id) INNER JOIN $table_user u ON (u.user_id=admin.user_id)
  2988. WHERE access_url_id ='".$access_url_id."'";
  2989. } else {
  2990. $sql = "SELECT admin.user_id, username, firstname, lastname, email FROM $table_admin as admin
  2991. INNER JOIN $table_user u ON (u.user_id=admin.user_id)";
  2992. }
  2993. $result = Database::query($sql);
  2994. $return = array();
  2995. if (Database::num_rows($result) > 0) {
  2996. while ($row = Database::fetch_array($result, 'ASSOC')) {
  2997. $return[$row['user_id']] = $row;
  2998. }
  2999. }
  3000. return $return;
  3001. }
  3002. /**
  3003. * Search an user (tags, first name, last name and email )
  3004. * @param string the tag
  3005. * @param int field id of the tag
  3006. * @param int where to start in the query
  3007. * @param int number of items
  3008. * @param bool get count or not
  3009. * @return array
  3010. */
  3011. public static function get_all_user_tags($tag, $field_id = 0, $from = 0, $number_of_items = 10, $getCount = false)
  3012. {
  3013. $user_table = Database::get_main_table(TABLE_MAIN_USER);
  3014. $table_user_tag = Database::get_main_table(TABLE_MAIN_TAG);
  3015. $table_user_tag_values = Database::get_main_table(TABLE_MAIN_USER_REL_TAG);
  3016. $access_url_rel_user_table = Database :: get_main_table(TABLE_MAIN_ACCESS_URL_REL_USER);
  3017. $tag = Database::escape_string($tag);
  3018. $field_id = intval($field_id);
  3019. $from = intval($from);
  3020. $number_of_items = intval($number_of_items);
  3021. $where_field = "";
  3022. if ($field_id != 0) {
  3023. $where_field = " field_id = $field_id AND ";
  3024. }
  3025. // all the information of the field
  3026. if ($getCount) {
  3027. $select = "SELECT count(DISTINCT u.user_id) count";
  3028. } else {
  3029. $select = "SELECT DISTINCT u.user_id, u.username, firstname, lastname, email, tag, picture_uri";
  3030. }
  3031. $sql = " $select
  3032. FROM $user_table u
  3033. INNER JOIN $access_url_rel_user_table url_rel_user ON (u.user_id = url_rel_user.user_id)
  3034. LEFT JOIN $table_user_tag_values uv ON (u.user_id AND uv.user_id AND uv.user_id = url_rel_user.user_id)
  3035. LEFT JOIN $table_user_tag ut ON (uv.tag_id = ut.id)
  3036. WHERE
  3037. ($where_field tag LIKE '$tag%') OR
  3038. (
  3039. u.firstname LIKE '%".$tag."%' OR
  3040. u.lastname LIKE '%".$tag."%' OR
  3041. u.username LIKE '%".$tag."%' OR
  3042. concat(u.firstname,' ',u.lastname) LIKE '%".$tag."%' OR
  3043. concat(u.lastname,' ',u.firstname) LIKE '%".$tag."%'
  3044. )
  3045. AND
  3046. url_rel_user.access_url_id=".api_get_current_access_url_id();
  3047. $keyword_active = true;
  3048. // only active users
  3049. if ($keyword_active) {
  3050. $sql .= " AND u.active='1'";
  3051. }
  3052. // avoid anonymous
  3053. $sql .= " AND u.status <> 6 ";
  3054. $sql .= " ORDER BY username";
  3055. $sql .= " LIMIT $from , $number_of_items";
  3056. $result = Database::query($sql);
  3057. $return = array();
  3058. if (Database::num_rows($result) > 0) {
  3059. if ($getCount) {
  3060. $row = Database::fetch_array($result, 'ASSOC');
  3061. return $row['count'];
  3062. }
  3063. while ($row = Database::fetch_array($result, 'ASSOC')) {
  3064. if (isset($return[$row['user_id']]) && !empty($return[$row['user_id']]['tag'])) {
  3065. $url = Display::url($row['tag'], api_get_path(WEB_PATH).'main/social/search.php?q='.$row['tag'], array('class' => 'tag'));
  3066. $row['tag'] = $url;
  3067. }
  3068. $return[$row['user_id']] = $row;
  3069. }
  3070. }
  3071. return $return;
  3072. }
  3073. /**
  3074. * Show the search form
  3075. * @param string the value of the search box
  3076. *
  3077. */
  3078. public static function get_search_form($query)
  3079. {
  3080. return '
  3081. <form method="GET" class="well form-search" action="'.api_get_path(WEB_PATH).'main/social/search.php">
  3082. <input placeholder="'.get_lang('UsersGroups').'" type="text" class="input-medium" value="'.api_htmlentities(Security::remove_XSS($query)).'" name="q"/> &nbsp;
  3083. <button class="btn" type="submit" value="search">'.get_lang('Search').'</button>
  3084. </form>';
  3085. }
  3086. /**
  3087. * Shows the user menu
  3088. */
  3089. public static function show_menu()
  3090. {
  3091. echo '<div class="actions">';
  3092. echo '<a href="/main/auth/profile.php">'.Display::return_icon('profile.png').' '.get_lang('PersonalData').'</a>';
  3093. echo '<a href="/main/messages/inbox.php">'.Display::return_icon('inbox.png').' '.get_lang('Inbox').'</a>';
  3094. echo '<a href="/main/messages/outbox.php">'.Display::return_icon('outbox.png').' '.get_lang('Outbox').'</a>';
  3095. echo '<span style="float:right; padding-top:7px;">'.
  3096. '<a href="/main/auth/profile.php?show=1">'.Display::return_icon('edit.gif').' '.get_lang('Configuration').'</a>';
  3097. '</span>';
  3098. echo '</div>';
  3099. }
  3100. /**
  3101. * Gives a list of course auto-register (field special_course)
  3102. * @return array list of course
  3103. * @author Jhon Hinojosa <jhon.hinojosa@dokeos.com>
  3104. * @deprecated this function is never use in chamilo, use CourseManager::get_special_course_list
  3105. * @since v1.8.6.2
  3106. */
  3107. public static function get_special_course_list()
  3108. {
  3109. // Database Table Definitions
  3110. $tbl_course_user = Database :: get_main_table(TABLE_MAIN_COURSE_USER);
  3111. $tbl_course = Database :: get_main_table(TABLE_MAIN_COURSE);
  3112. $tbl_course_field = Database :: get_main_table(TABLE_MAIN_COURSE_FIELD);
  3113. $tbl_course_field_value = Database :: get_main_table(TABLE_MAIN_COURSE_FIELD_VALUES);
  3114. $tbl_user_course_category = Database :: get_user_personal_table(TABLE_USER_COURSE_CATEGORY);
  3115. //we filter the courses from the URL
  3116. $join_access_url = $where_access_url = '';
  3117. if (api_get_multiple_access_url()) {
  3118. $access_url_id = api_get_current_access_url_id();
  3119. $tbl_url_course = Database :: get_main_table(TABLE_MAIN_ACCESS_URL_REL_COURSE);
  3120. $join_access_url = "LEFT JOIN $tbl_url_course url_rel_course ON url_rel_course.course_code= course.code";
  3121. $where_access_url = " AND access_url_id = $access_url_id ";
  3122. }
  3123. // Filter special courses
  3124. $sql_special_course = "SELECT course_code FROM $tbl_course_field_value tcfv INNER JOIN $tbl_course_field tcf ON ".
  3125. " tcfv.field_id = tcf.id WHERE tcf.field_variable = 'special_course' AND tcfv.field_value = 1 ";
  3126. $special_course_result = Database::query($sql_special_course);
  3127. $code_special_courses = '';
  3128. if (Database::num_rows($special_course_result) > 0) {
  3129. $special_course_list = array();
  3130. while ($result_row = Database::fetch_array($special_course_result)) {
  3131. $special_course_list[] = '"'.$result_row['course_code'].'"';
  3132. }
  3133. $code_special_courses = ' course.code IN ('.join($special_course_list, ',').') ';
  3134. }
  3135. // variable initialisation
  3136. $course_list_sql = '';
  3137. $course_list = array();
  3138. if (!empty($code_special_courses)) {
  3139. $course_list_sql = "SELECT course.code k, course.directory d, course.visual_code c, course.db_name db, course.title i, course.tutor_name t, course.course_language l, course_rel_user.status s, course_rel_user.sort sort, course_rel_user.user_course_cat user_course_cat
  3140. FROM ".$tbl_course_user." course_rel_user
  3141. LEFT JOIN ".$tbl_course." course
  3142. ON course.code = course_rel_user.course_code
  3143. LEFT JOIN ".$tbl_user_course_category." user_course_category
  3144. ON course_rel_user.user_course_cat = user_course_category.id
  3145. $join_access_url
  3146. WHERE $code_special_courses $where_access_url
  3147. GROUP BY course.code
  3148. ORDER BY user_course_category.sort,course.title,course_rel_user.sort ASC";
  3149. $course_list_sql_result = Database::query($course_list_sql);
  3150. while ($result_row = Database::fetch_array($course_list_sql_result)) {
  3151. $course_list[] = $result_row;
  3152. }
  3153. }
  3154. return $course_list;
  3155. }
  3156. /**
  3157. * Allow to register contact to social network
  3158. * @param int user friend id
  3159. * @param int user id
  3160. * @param int relation between users see constants definition
  3161. */
  3162. public static function relate_users($friend_id, $my_user_id, $relation_type)
  3163. {
  3164. $tbl_my_friend = Database :: get_main_table(TABLE_MAIN_USER_REL_USER);
  3165. $friend_id = intval($friend_id);
  3166. $my_user_id = intval($my_user_id);
  3167. $relation_type = intval($relation_type);
  3168. $sql = 'SELECT COUNT(*) as count FROM '.$tbl_my_friend.' WHERE friend_user_id='.$friend_id.' AND user_id='.$my_user_id.' AND relation_type <> '.USER_RELATION_TYPE_RRHH.' ';
  3169. $result = Database::query($sql);
  3170. $row = Database :: fetch_array($result, 'ASSOC');
  3171. $current_date = date('Y-m-d H:i:s');
  3172. if ($row['count'] == 0) {
  3173. $sql_i = 'INSERT INTO '.$tbl_my_friend.'(friend_user_id,user_id,relation_type,last_edit)values('.$friend_id.','.$my_user_id.','.$relation_type.',"'.$current_date.'");';
  3174. Database::query($sql_i);
  3175. return true;
  3176. } else {
  3177. $sql = 'SELECT COUNT(*) as count, relation_type FROM '.$tbl_my_friend.' WHERE friend_user_id='.$friend_id.' AND user_id='.$my_user_id.' AND relation_type <> '.USER_RELATION_TYPE_RRHH.' ';
  3178. $result = Database::query($sql);
  3179. $row = Database :: fetch_array($result, 'ASSOC');
  3180. if ($row['count'] == 1) {
  3181. //only for the case of a RRHH
  3182. if ($row['relation_type'] != $relation_type && $relation_type == USER_RELATION_TYPE_RRHH) {
  3183. $sql_i = 'INSERT INTO '.$tbl_my_friend.'(friend_user_id,user_id,relation_type,last_edit)values('.$friend_id.','.$my_user_id.','.$relation_type.',"'.$current_date.'");';
  3184. } else {
  3185. $sql_i = 'UPDATE '.$tbl_my_friend.' SET relation_type='.$relation_type.' WHERE friend_user_id='.$friend_id.' AND user_id='.$my_user_id;
  3186. }
  3187. Database::query($sql_i);
  3188. return true;
  3189. } else {
  3190. return false;
  3191. }
  3192. }
  3193. }
  3194. /**
  3195. * Deletes a contact
  3196. * @param int user friend id
  3197. * @param bool true will delete ALL friends relationship from $friend_id
  3198. * @author isaac flores paz <isaac.flores@dokeos.com>
  3199. * @author Julio Montoya <gugli100@gmail.com> Cleaning code
  3200. */
  3201. public static function remove_user_rel_user($friend_id, $real_removed = false, $with_status_condition = '')
  3202. {
  3203. $tbl_my_friend = Database :: get_main_table(TABLE_MAIN_USER_REL_USER);
  3204. $tbl_my_message = Database :: get_main_table(TABLE_MAIN_MESSAGE);
  3205. $friend_id = intval($friend_id);
  3206. if ($real_removed) {
  3207. //Delete user friend
  3208. /*
  3209. $sql_delete_relationship1 = 'UPDATE ' . $tbl_my_friend .' SET relation_type='.USER_RELATION_TYPE_DELETED.' WHERE friend_user_id='.$friend_id;
  3210. $sql_delete_relationship2 = 'UPDATE ' . $tbl_my_friend . ' SET relation_type='.USER_RELATION_TYPE_DELETED.' WHERE user_id=' . $friend_id;
  3211. Database::query($sql_delete_relationship1);
  3212. Database::query($sql_delete_relationship2); */
  3213. $extra_condition = '';
  3214. if ($with_status_condition != '') {
  3215. $extra_condition = ' AND relation_type = '.intval($with_status_condition);
  3216. }
  3217. $sql_delete_relationship1 = 'DELETE FROM '.$tbl_my_friend.' WHERE relation_type <> '.USER_RELATION_TYPE_RRHH.' AND friend_user_id='.$friend_id.' '.$extra_condition;
  3218. $sql_delete_relationship2 = 'DELETE FROM '.$tbl_my_friend.' WHERE relation_type <> '.USER_RELATION_TYPE_RRHH.' AND user_id='.$friend_id.' '.$extra_condition;
  3219. Database::query($sql_delete_relationship1);
  3220. Database::query($sql_delete_relationship2);
  3221. } else {
  3222. $user_id = api_get_user_id();
  3223. $sql = 'SELECT COUNT(*) as count FROM '.$tbl_my_friend.' WHERE user_id='.$user_id.' AND relation_type NOT IN('.USER_RELATION_TYPE_DELETED.', '.USER_RELATION_TYPE_RRHH.') AND friend_user_id='.$friend_id;
  3224. $result = Database::query($sql);
  3225. $row = Database :: fetch_array($result, 'ASSOC');
  3226. if ($row['count'] == 1) {
  3227. //Delete user rel user
  3228. $sql_i = 'UPDATE '.$tbl_my_friend.' SET relation_type='.USER_RELATION_TYPE_DELETED.' WHERE user_id='.$user_id.' AND friend_user_id='.$friend_id;
  3229. $sql_j = 'UPDATE '.$tbl_my_message.' SET msg_status='.MESSAGE_STATUS_INVITATION_DENIED.' WHERE user_receiver_id='.$user_id.' AND user_sender_id='.$friend_id.' AND update_date="0000-00-00 00:00:00" ';
  3230. //Delete user
  3231. $sql_ij = 'UPDATE '.$tbl_my_friend.' SET relation_type='.USER_RELATION_TYPE_DELETED.' WHERE user_id='.$friend_id.' AND friend_user_id='.$user_id;
  3232. $sql_ji = 'UPDATE '.$tbl_my_message.' SET msg_status='.MESSAGE_STATUS_INVITATION_DENIED.' WHERE user_receiver_id='.$friend_id.' AND user_sender_id='.$user_id.' AND update_date="0000-00-00 00:00:00" ';
  3233. Database::query($sql_i);
  3234. Database::query($sql_j);
  3235. Database::query($sql_ij);
  3236. Database::query($sql_ji);
  3237. }
  3238. }
  3239. }
  3240. /**
  3241. * get users followed by human resource manager
  3242. * @param int $userId
  3243. * @param int $userStatus (STUDENT, COURSEMANAGER, etc)
  3244. * @param bool $getOnlyUserId
  3245. * @param bool $getSql
  3246. * @param bool $getCount
  3247. * @param int $from
  3248. * @param int $numberItems
  3249. * @param int $column
  3250. * @param string $direction
  3251. * @param int $active
  3252. * @param string $lastConnectionDate
  3253. * @return array users
  3254. */
  3255. public static function get_users_followed_by_drh(
  3256. $userId,
  3257. $userStatus = 0,
  3258. $getOnlyUserId = false,
  3259. $getSql = false,
  3260. $getCount = false,
  3261. $from = null,
  3262. $numberItems = null,
  3263. $column = null,
  3264. $direction = null,
  3265. $active = null,
  3266. $lastConnectionDate = null
  3267. ) {
  3268. return self::getUsersFollowedByUser(
  3269. $userId,
  3270. $userStatus,
  3271. $getOnlyUserId,
  3272. $getSql,
  3273. $getCount,
  3274. $from,
  3275. $numberItems,
  3276. $column,
  3277. $direction,
  3278. $active,
  3279. $lastConnectionDate,
  3280. DRH
  3281. );
  3282. }
  3283. /**
  3284. * Get users followed by human resource manager
  3285. * @param int $userId
  3286. * @param int $userStatus Filter users by status (STUDENT, COURSEMANAGER, etc)
  3287. * @param bool $getOnlyUserId
  3288. * @param bool $getSql
  3289. * @param bool $getCount
  3290. * @param int $from
  3291. * @param int $numberItems
  3292. * @param int $column
  3293. * @param string $direction
  3294. * @param int $active
  3295. * @param string $lastConnectionDate
  3296. * @param int $status the function is called by who? COURSEMANAGER, DRH?
  3297. * @return array users
  3298. */
  3299. public static function getUsersFollowedByUser(
  3300. $userId,
  3301. $userStatus = null,
  3302. $getOnlyUserId = false,
  3303. $getSql = false,
  3304. $getCount = false,
  3305. $from = null,
  3306. $numberItems = null,
  3307. $column = null,
  3308. $direction = null,
  3309. $active = null,
  3310. $lastConnectionDate = null,
  3311. $status = null
  3312. ) {
  3313. // Database Table Definitions
  3314. $tbl_user = Database::get_main_table(TABLE_MAIN_USER);
  3315. $tbl_user_rel_user = Database::get_main_table(TABLE_MAIN_USER_REL_USER);
  3316. $tbl_user_rel_access_url = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_USER);
  3317. $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
  3318. $tbl_course = Database::get_main_table(TABLE_MAIN_COURSE);
  3319. $tbl_course_user = Database::get_main_table(TABLE_MAIN_COURSE_USER);
  3320. $tbl_course_rel_access_url = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_COURSE);
  3321. $tbl_session_rel_course_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
  3322. $tbl_session_rel_access_url = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
  3323. $tbl_session_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_USER);
  3324. $userId = intval($userId);
  3325. $limitCondition = null;
  3326. if (isset($from) && isset($numberItems)) {
  3327. $from = intval($from);
  3328. $numberItems = intval($numberItems);
  3329. $limitCondition = "LIMIT $from, $numberItems";
  3330. }
  3331. $column = Database::escape_string($column);
  3332. $direction = in_array(strtolower($direction), array('asc', 'desc')) ? $direction : null;
  3333. $userConditions = '';
  3334. if (!empty($userStatus)) {
  3335. $userConditions .= ' AND u.status = '.$userStatus;
  3336. }
  3337. $select = " SELECT DISTINCT u.user_id, u.username, u.lastname, u.firstname, u.email ";
  3338. if ($getOnlyUserId) {
  3339. $select = " SELECT DISTINCT u.user_id";
  3340. }
  3341. $masterSelect = "SELECT DISTINCT * FROM ";
  3342. if ($getCount) {
  3343. $masterSelect = "SELECT COUNT(DISTINCT(user_id)) as count FROM ";
  3344. $select = " SELECT DISTINCT(u.user_id) ";
  3345. }
  3346. if (!is_null($active)) {
  3347. $active = intval($active);
  3348. $userConditions .= " AND u.active = $active ";
  3349. }
  3350. if (!empty($lastConnectionDate)) {
  3351. $lastConnectionDate = Database::escape_string($lastConnectionDate);
  3352. $userConditions .= " AND u.last_login <= '$lastConnectionDate' ";
  3353. }
  3354. $courseConditions = null;
  3355. $sessionConditionsCoach = null;
  3356. $sessionConditionsTeacher = null;
  3357. $drhConditions = null;
  3358. $teacherSelect = null;
  3359. switch($status) {
  3360. case DRH:
  3361. $drhConditions .= " AND
  3362. friend_user_id = '$userId' AND
  3363. relation_type = '".USER_RELATION_TYPE_RRHH."'
  3364. ";
  3365. break;
  3366. case COURSEMANAGER:
  3367. $drhConditions .= " AND
  3368. friend_user_id = '$userId' AND
  3369. relation_type = '".USER_RELATION_TYPE_RRHH."'
  3370. ";
  3371. $sessionConditionsCoach .= " AND
  3372. (s.id_coach = '$userId')
  3373. ";
  3374. $sessionConditionsTeacher .= " AND
  3375. (scu.status = 2 AND scu.id_user = '$userId')
  3376. ";
  3377. $teacherSelect =
  3378. "UNION ALL (
  3379. $select
  3380. FROM $tbl_user u
  3381. INNER JOIN $tbl_session_rel_user sru ON (sru.id_user = u.user_id)
  3382. WHERE
  3383. sru.id_session IN (
  3384. SELECT DISTINCT(s.id) FROM $tbl_session s INNER JOIN
  3385. $tbl_session_rel_access_url
  3386. WHERE access_url_id = ".api_get_current_access_url_id()."
  3387. $sessionConditionsCoach
  3388. UNION (
  3389. SELECT DISTINCT(s.id) FROM $tbl_session s
  3390. INNER JOIN $tbl_session_rel_access_url url
  3391. ON (url.session_id = s.id)
  3392. INNER JOIN $tbl_session_rel_course_rel_user scu
  3393. ON (scu.id_session = s.id)
  3394. WHERE access_url_id = ".api_get_current_access_url_id()."
  3395. $sessionConditionsTeacher
  3396. )
  3397. )
  3398. $userConditions
  3399. )
  3400. UNION ALL(
  3401. $select
  3402. FROM $tbl_user u
  3403. INNER JOIN $tbl_course_user cu ON (cu.user_id = u.user_id)
  3404. WHERE cu.course_code IN (
  3405. SELECT DISTINCT(course_code) FROM $tbl_course_user
  3406. WHERE user_id = $userId AND status = ".COURSEMANAGER."
  3407. )
  3408. $userConditions
  3409. )"
  3410. ;
  3411. break;
  3412. }
  3413. $join = null;
  3414. $sql = " $masterSelect
  3415. (
  3416. (
  3417. $select
  3418. FROM $tbl_user u
  3419. INNER JOIN $tbl_user_rel_user uru ON (uru.user_id = u.user_id)
  3420. LEFT JOIN $tbl_user_rel_access_url a ON (a.user_id = u.user_id)
  3421. $join
  3422. WHERE
  3423. access_url_id = ".api_get_current_access_url_id()."
  3424. $drhConditions
  3425. $userConditions
  3426. )
  3427. $teacherSelect
  3428. ) as t1";
  3429. if ($getSql) {
  3430. return $sql;
  3431. }
  3432. if ($getCount) {
  3433. $result = Database::query($sql);
  3434. $row = Database::fetch_array($result);
  3435. //var_dump($sql);
  3436. //var_dump($row);
  3437. return $row['count'];
  3438. }
  3439. $orderBy = null;
  3440. if (api_is_western_name_order()) {
  3441. $orderBy .= " ORDER BY firstname, lastname ";
  3442. } else {
  3443. $orderBy .= " ORDER BY lastname, firstname ";
  3444. }
  3445. if (!empty($column) && !empty($direction)) {
  3446. // Fixing order due the UNIONs
  3447. $column = str_replace('u.', '', $column);
  3448. $orderBy = " ORDER BY $column $direction ";
  3449. }
  3450. $sql .= $orderBy;
  3451. $sql .= $limitCondition;
  3452. $result = Database::query($sql);
  3453. $users = array();
  3454. if (Database::num_rows($result) > 0) {
  3455. //var_dump($sql);
  3456. while ($row = Database::fetch_array($result)) {
  3457. $users[$row['user_id']] = $row;
  3458. }
  3459. }
  3460. return $users;
  3461. }
  3462. /**
  3463. * Subscribes users to human resource manager (Dashboard feature)
  3464. * @param int hr dept id
  3465. * @param array Users id
  3466. * @param int affected rows
  3467. * */
  3468. public static function suscribe_users_to_hr_manager($hr_dept_id, $users_id)
  3469. {
  3470. // Database Table Definitions
  3471. $tbl_user_rel_user = Database::get_main_table(TABLE_MAIN_USER_REL_USER);
  3472. $tbl_user_rel_access_url = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_USER);
  3473. $hr_dept_id = intval($hr_dept_id);
  3474. $affected_rows = 0;
  3475. if (api_get_multiple_access_url()) {
  3476. //Deleting assigned users to hrm_id
  3477. $sql = "SELECT s.user_id FROM $tbl_user_rel_user s
  3478. INNER JOIN $tbl_user_rel_access_url a
  3479. ON (a.user_id = s.user_id)
  3480. WHERE
  3481. friend_user_id = $hr_dept_id AND
  3482. relation_type = '".USER_RELATION_TYPE_RRHH."' AND
  3483. access_url_id = ".api_get_current_access_url_id()."";
  3484. } else {
  3485. $sql = "SELECT user_id FROM $tbl_user_rel_user
  3486. WHERE
  3487. friend_user_id = $hr_dept_id AND
  3488. relation_type = '".USER_RELATION_TYPE_RRHH."' ";
  3489. }
  3490. $result = Database::query($sql);
  3491. if (Database::num_rows($result) > 0) {
  3492. while ($row = Database::fetch_array($result)) {
  3493. $sql = "DELETE FROM $tbl_user_rel_user
  3494. WHERE
  3495. user_id = '{$row['user_id']}' AND
  3496. friend_user_id = $hr_dept_id AND
  3497. relation_type = '".USER_RELATION_TYPE_RRHH."' ";
  3498. Database::query($sql);
  3499. }
  3500. }
  3501. // Inserting new user list
  3502. if (is_array($users_id)) {
  3503. foreach ($users_id as $user_id) {
  3504. $user_id = intval($user_id);
  3505. $sql = "INSERT IGNORE INTO $tbl_user_rel_user(user_id, friend_user_id, relation_type)
  3506. VALUES ('$user_id', $hr_dept_id, '".USER_RELATION_TYPE_RRHH."')";
  3507. Database::query($sql);
  3508. $affected_rows = Database::affected_rows();
  3509. }
  3510. }
  3511. return $affected_rows;
  3512. }
  3513. /**
  3514. * This function check if an user is followed by human resources manager
  3515. * @param int User id
  3516. * @param int Human resources manager
  3517. * @return bool
  3518. */
  3519. public static function is_user_followed_by_drh($user_id, $hr_dept_id)
  3520. {
  3521. // Database table and variables Definitions
  3522. $tbl_user_rel_user = Database::get_main_table(TABLE_MAIN_USER_REL_USER);
  3523. $user_id = intval($user_id);
  3524. $hr_dept_id = intval($hr_dept_id);
  3525. $result = false;
  3526. $sql = "SELECT user_id FROM $tbl_user_rel_user
  3527. WHERE
  3528. user_id='$user_id' AND
  3529. friend_user_id='$hr_dept_id' AND
  3530. relation_type = ".USER_RELATION_TYPE_RRHH;
  3531. $rs = Database::query($sql);
  3532. if (Database::num_rows($rs) > 0) {
  3533. $result = true;
  3534. }
  3535. return $result;
  3536. }
  3537. /**
  3538. * get user id of teacher or session administrator
  3539. * @param string The course id
  3540. * @return int The user id
  3541. */
  3542. public static function get_user_id_of_course_admin_or_session_admin($course_id)
  3543. {
  3544. $session = api_get_session_id();
  3545. $table_user = Database::get_main_table(TABLE_MAIN_USER);
  3546. $table_course_user = Database::get_main_table(TABLE_MAIN_COURSE_USER);
  3547. $table_session_course_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
  3548. if ($session == 0 || is_null($session)) {
  3549. $sql = 'SELECT u.user_id FROM '.$table_user.' u
  3550. INNER JOIN '.$table_course_user.' ru ON ru.user_id=u.user_id
  3551. WHERE
  3552. ru.status = 1 AND
  3553. ru.course_code = "'.Database::escape_string($course_id).'" ';
  3554. $rs = Database::query($sql);
  3555. $num_rows = Database::num_rows($rs);
  3556. if ($num_rows == 1) {
  3557. $row = Database::fetch_array($rs);
  3558. return $row['user_id'];
  3559. } else {
  3560. $my_num_rows = $num_rows;
  3561. $my_user_id = Database::result($rs, $my_num_rows - 1, 'user_id');
  3562. return $my_user_id;
  3563. }
  3564. } elseif ($session > 0) {
  3565. $sql = 'SELECT u.user_id FROM '.$table_user.' u
  3566. INNER JOIN '.$table_session_course_user.' sru
  3567. ON sru.id_user=u.user_id
  3568. WHERE
  3569. sru.course_code="'.Database::escape_string($course_id).'" AND
  3570. sru.status=2';
  3571. $rs = Database::query($sql);
  3572. $row = Database::fetch_array($rs);
  3573. return $row['user_id'];
  3574. }
  3575. }
  3576. /**
  3577. * Determines if a user is a gradebook certified
  3578. * @param int The category id of gradebook
  3579. * @param int The user id
  3580. * @return boolean
  3581. */
  3582. public static function is_user_certified($cat_id, $user_id)
  3583. {
  3584. $table_certificate = Database::get_main_table(TABLE_MAIN_GRADEBOOK_CERTIFICATE);
  3585. $sql = 'SELECT path_certificate FROM '.$table_certificate.'
  3586. WHERE
  3587. cat_id="'.Database::escape_string($cat_id).'" AND
  3588. user_id="'.Database::escape_string($user_id).'"';
  3589. $rs = Database::query($sql);
  3590. $row = Database::fetch_array($rs);
  3591. if ($row['path_certificate'] == '' || is_null($row['path_certificate'])) {
  3592. return false;
  3593. } else {
  3594. return true;
  3595. }
  3596. }
  3597. /**
  3598. * Gets the info about a gradebook certificate for a user by course
  3599. * @param string The course code
  3600. * @param int The user id
  3601. * @return array if there is not information return false
  3602. */
  3603. public static function get_info_gradebook_certificate($course_code, $user_id)
  3604. {
  3605. $tbl_grade_certificate = Database::get_main_table(TABLE_MAIN_GRADEBOOK_CERTIFICATE);
  3606. $tbl_grade_category = Database::get_main_table(TABLE_MAIN_GRADEBOOK_CATEGORY);
  3607. $session_id = api_get_session_id();
  3608. if (empty($session_id)) {
  3609. $session_condition = ' AND (session_id = "" OR session_id = 0 OR session_id IS NULL )';
  3610. } else {
  3611. $session_condition = " AND session_id = $session_id";
  3612. }
  3613. // Getting gradebook score.
  3614. require_once api_get_path(SYS_CODE_PATH).'gradebook/lib/be.inc.php';
  3615. require_once api_get_path(SYS_CODE_PATH).'gradebook/lib/scoredisplay.class.php';
  3616. $sql = 'SELECT * FROM '.$tbl_grade_certificate.' WHERE cat_id = (SELECT id FROM '.$tbl_grade_category.'
  3617. WHERE
  3618. course_code = "'.Database::escape_string($course_code).'" '.$session_condition.' LIMIT 1 ) AND
  3619. user_id='.Database::escape_string($user_id);
  3620. $rs = Database::query($sql);
  3621. if (Database::num_rows($rs) > 0) {
  3622. $row = Database::fetch_array($rs, 'ASSOC');
  3623. $score = $row['score_certificate'];
  3624. $category_id = $row['cat_id'];
  3625. $cat = Category::load($category_id);
  3626. $displayscore = ScoreDisplay::instance();
  3627. if (isset($cat) && $displayscore->is_custom()) {
  3628. $grade = $displayscore->display_score(array($score, $cat[0]->get_weight()), SCORE_DIV_PERCENT_WITH_CUSTOM);
  3629. } else {
  3630. $grade = $displayscore->display_score(array($score, $cat[0]->get_weight()));
  3631. }
  3632. $row['grade'] = $grade;
  3633. return $row;
  3634. }
  3635. return false;
  3636. }
  3637. /**
  3638. * Gets the user path of user certificated
  3639. * @param int The user id
  3640. * @return array containing path_certificate and cat_id
  3641. */
  3642. public static function get_user_path_certificate($user_id)
  3643. {
  3644. $my_certificate = array();
  3645. $table_certificate = Database::get_main_table(TABLE_MAIN_GRADEBOOK_CERTIFICATE);
  3646. $table_gradebook_category = Database::get_main_table(TABLE_MAIN_GRADEBOOK_CATEGORY);
  3647. $session_id = api_get_session_id();
  3648. $user_id = intval($user_id);
  3649. if ($session_id == 0 || is_null($session_id)) {
  3650. $sql_session = 'AND (session_id='.Database::escape_string($session_id).' OR isnull(session_id)) ';
  3651. } elseif ($session_id > 0) {
  3652. $sql_session = 'AND session_id='.Database::escape_string($session_id);
  3653. } else {
  3654. $sql_session = '';
  3655. }
  3656. $sql = "SELECT tc.path_certificate,tc.cat_id,tgc.course_code,tgc.name
  3657. FROM $table_certificate tc, $table_gradebook_category tgc
  3658. WHERE tgc.id = tc.cat_id AND tc.user_id='$user_id'
  3659. ORDER BY tc.date_certificate DESC limit 5";
  3660. $rs = Database::query($sql);
  3661. while ($row = Database::fetch_array($rs)) {
  3662. $my_certificate[] = $row;
  3663. }
  3664. return $my_certificate;
  3665. }
  3666. /**
  3667. * This function check if the user is a coach inside session course
  3668. * @param int User id
  3669. * @param string Course code
  3670. * @param int Session id
  3671. * @return bool True if the user is a coach
  3672. *
  3673. */
  3674. public static function is_session_course_coach($user_id, $course_code, $session_id)
  3675. {
  3676. $tbl_session_course_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
  3677. // Protect data
  3678. $user_id = intval($user_id);
  3679. $course_code = Database::escape_string($course_code);
  3680. $session_id = intval($session_id);
  3681. $result = false;
  3682. $sql = "SELECT id_session FROM $tbl_session_course_rel_user
  3683. WHERE
  3684. id_session=$session_id AND
  3685. course_code='$course_code' AND
  3686. id_user = $user_id AND
  3687. status = 2 ";
  3688. $res = Database::query($sql);
  3689. if (Database::num_rows($res) > 0) {
  3690. $result = true;
  3691. }
  3692. return $result;
  3693. }
  3694. /**
  3695. * This function returns an icon path that represents the favicon of the website of which the url given.
  3696. * Defaults to the current Chamilo favicon
  3697. * @param string URL of website where to look for favicon.ico
  3698. * @param string Optional second URL of website where to look for favicon.ico
  3699. * @return string Path of icon to load
  3700. */
  3701. public static function get_favicon_from_url($url1, $url2 = null)
  3702. {
  3703. $icon_link = '';
  3704. $url = $url1;
  3705. if (empty($url1)) {
  3706. $url = $url2;
  3707. if (empty($url)) {
  3708. $url = api_get_access_url(api_get_current_access_url_id());
  3709. $url = $url[0];
  3710. }
  3711. }
  3712. if (!empty($url)) {
  3713. $pieces = parse_url($url);
  3714. $icon_link = $pieces['scheme'].'://'.$pieces['host'].'/favicon.ico';
  3715. }
  3716. return $icon_link;
  3717. }
  3718. /**
  3719. *
  3720. * @param int student id
  3721. * @param int years
  3722. * @param bool show warning_message
  3723. * @param bool return_timestamp
  3724. */
  3725. public static function delete_inactive_student($student_id, $years = 2, $warning_message = false, $return_timestamp = false)
  3726. {
  3727. $tbl_track_login = Database :: get_statistic_table(TABLE_STATISTIC_TRACK_E_LOGIN);
  3728. $sql = 'SELECT login_date FROM '.$tbl_track_login.'
  3729. WHERE login_user_id = '.intval($student_id).'
  3730. ORDER BY login_date DESC LIMIT 0,1';
  3731. if (empty($years)) {
  3732. $years = 1;
  3733. }
  3734. $inactive_time = $years * 31536000; //1 year
  3735. $rs = Database::query($sql);
  3736. if (Database::num_rows($rs) > 0) {
  3737. if ($last_login_date = Database::result($rs, 0, 0)) {
  3738. $last_login_date = api_get_local_time($last_login_date, null, date_default_timezone_get());
  3739. if ($return_timestamp) {
  3740. return api_strtotime($last_login_date);
  3741. } else {
  3742. if (!$warning_message) {
  3743. return api_format_date($last_login_date, DATE_FORMAT_SHORT);
  3744. } else {
  3745. $timestamp = api_strtotime($last_login_date);
  3746. $currentTimestamp = time();
  3747. //If the last connection is > than 7 days, the text is red
  3748. //345600 = 7 days in seconds 63072000= 2 ans
  3749. // if ($currentTimestamp - $timestamp > 184590 )
  3750. if ($currentTimestamp - $timestamp > $inactive_time && UserManager::delete_user($student_id)) {
  3751. Display :: display_normal_message(get_lang('UserDeleted'));
  3752. echo '<p>', 'id', $student_id, ':', $last_login_date, '</p>';
  3753. }
  3754. }
  3755. }
  3756. }
  3757. }
  3758. return false;
  3759. }
  3760. /**
  3761. * @param $form
  3762. * @param $extra_data
  3763. * @param $form_name
  3764. * @param bool $admin_permissions
  3765. * @param null $user_id
  3766. * @return array
  3767. */
  3768. static function set_extra_fields_in_form($form, $extra_data, $form_name, $admin_permissions = false, $user_id = null)
  3769. {
  3770. $user_id = intval($user_id);
  3771. // EXTRA FIELDS
  3772. $extra = UserManager::get_extra_fields(0, 50, 5, 'ASC');
  3773. $jquery_ready_content = null;
  3774. foreach ($extra as $field_details) {
  3775. if (!$admin_permissions) {
  3776. if ($field_details[6] == 0) {
  3777. continue;
  3778. }
  3779. }
  3780. switch ($field_details[2]) {
  3781. case self::USER_FIELD_TYPE_TEXT:
  3782. $form->addElement('text', 'extra_'.$field_details[1], $field_details[3], array('size' => 40));
  3783. $form->applyFilter('extra_'.$field_details[1], 'stripslashes');
  3784. $form->applyFilter('extra_'.$field_details[1], 'trim');
  3785. if (!$admin_permissions) {
  3786. if ($field_details[7] == 0)
  3787. $form->freeze('extra_'.$field_details[1]);
  3788. }
  3789. break;
  3790. case self::USER_FIELD_TYPE_TEXTAREA:
  3791. $form->add_html_editor(
  3792. 'extra_'.$field_details[1],
  3793. $field_details[3],
  3794. false,
  3795. false,
  3796. array('ToolbarSet' => 'Profile', 'Width' => '100%', 'Height' => '130')
  3797. );
  3798. //$form->addElement('textarea', 'extra_'.$field_details[1], $field_details[3], array('size' => 80));
  3799. $form->applyFilter('extra_'.$field_details[1], 'stripslashes');
  3800. $form->applyFilter('extra_'.$field_details[1], 'trim');
  3801. if (!$admin_permissions) {
  3802. if ($field_details[7] == 0)
  3803. $form->freeze('extra_'.$field_details[1]);
  3804. }
  3805. break;
  3806. case self::USER_FIELD_TYPE_RADIO:
  3807. $group = array();
  3808. foreach ($field_details[9] as $option_id => $option_details) {
  3809. $options[$option_details[1]] = $option_details[2];
  3810. $group[] = & HTML_QuickForm::createElement(
  3811. 'radio',
  3812. 'extra_'.$field_details[1],
  3813. $option_details[1],
  3814. $option_details[2].'<br />',
  3815. $option_details[1]
  3816. );
  3817. }
  3818. $form->addGroup($group, 'extra_'.$field_details[1], $field_details[3], '');
  3819. if (!$admin_permissions) {
  3820. if ($field_details[7] == 0)
  3821. $form->freeze('extra_'.$field_details[1]);
  3822. }
  3823. break;
  3824. case self::USER_FIELD_TYPE_SELECT:
  3825. $get_lang_variables = false;
  3826. if (in_array($field_details[1], array('mail_notify_message', 'mail_notify_invitation', 'mail_notify_group_message'))) {
  3827. $get_lang_variables = true;
  3828. }
  3829. $options = array();
  3830. foreach ($field_details[9] as $option_id => $option_details) {
  3831. //$options[$option_details[1]] = $option_details[2];
  3832. if ($get_lang_variables) {
  3833. $options[$option_details[1]] = get_lang($option_details[2]);
  3834. } else {
  3835. $options[$option_details[1]] = $option_details[2];
  3836. }
  3837. }
  3838. if ($get_lang_variables) {
  3839. $field_details[3] = get_lang($field_details[3]);
  3840. }
  3841. $form->addElement(
  3842. 'select',
  3843. 'extra_'.$field_details[1],
  3844. $field_details[3],
  3845. $options,
  3846. array('class' => 'chzn-select', 'id' => 'extra_'.$field_details[1])
  3847. );
  3848. if (!$admin_permissions) {
  3849. if ($field_details[7] == 0)
  3850. $form->freeze('extra_'.$field_details[1]);
  3851. }
  3852. break;
  3853. case self::USER_FIELD_TYPE_SELECT_MULTIPLE:
  3854. $options = array();
  3855. foreach ($field_details[9] as $option_id => $option_details) {
  3856. $options[$option_details[1]] = $option_details[2];
  3857. }
  3858. $form->addElement('select', 'extra_'.$field_details[1], $field_details[3], $options, array('multiple' => 'multiple'));
  3859. if (!$admin_permissions) {
  3860. if ($field_details[7] == 0)
  3861. $form->freeze('extra_'.$field_details[1]);
  3862. }
  3863. break;
  3864. case self::USER_FIELD_TYPE_DATE:
  3865. $form->addElement('datepickerdate', 'extra_'.$field_details[1], $field_details[3], array('form_name' => $form_name));
  3866. $form->_elements[$form->_elementIndex['extra_'.$field_details[1]]]->setLocalOption('minYear', 1900);
  3867. $defaults['extra_'.$field_details[1]] = date('Y-m-d 12:00:00');
  3868. $form->setDefaults($defaults);
  3869. if (!$admin_permissions) {
  3870. if ($field_details[7] == 0)
  3871. $form->freeze('extra_'.$field_details[1]);
  3872. }
  3873. $form->applyFilter('theme', 'trim');
  3874. break;
  3875. case self::USER_FIELD_TYPE_DATETIME:
  3876. $form->addElement('datepicker', 'extra_'.$field_details[1], $field_details[3], array('form_name' => $form_name));
  3877. $form->_elements[$form->_elementIndex['extra_'.$field_details[1]]]->setLocalOption('minYear', 1900);
  3878. $defaults['extra_'.$field_details[1]] = date('Y-m-d 12:00:00');
  3879. $form->setDefaults($defaults);
  3880. if (!$admin_permissions) {
  3881. if ($field_details[7] == 0)
  3882. $form->freeze('extra_'.$field_details[1]);
  3883. }
  3884. $form->applyFilter('theme', 'trim');
  3885. break;
  3886. case self::USER_FIELD_TYPE_DOUBLE_SELECT:
  3887. foreach ($field_details[9] as $key => $element) {
  3888. if ($element[2][0] == '*') {
  3889. $values['*'][$element[0]] = str_replace('*', '', $element[2]);
  3890. } else {
  3891. $values[0][$element[0]] = $element[2];
  3892. }
  3893. }
  3894. $group = '';
  3895. $group[] = & HTML_QuickForm::createElement('select', 'extra_'.$field_details[1], '', $values[0], '');
  3896. $group[] = & HTML_QuickForm::createElement('select', 'extra_'.$field_details[1].'*', '', $values['*'], '');
  3897. $form->addGroup($group, 'extra_'.$field_details[1], $field_details[3], '&nbsp;');
  3898. if (!$admin_permissions) {
  3899. if ($field_details[7] == 0)
  3900. $form->freeze('extra_'.$field_details[1]);
  3901. }
  3902. /* Recoding the selected values for double : if the user has
  3903. selected certain values, we have to assign them to the
  3904. correct select form */
  3905. if (array_key_exists('extra_'.$field_details[1], $extra_data)) {
  3906. // exploding all the selected values (of both select forms)
  3907. $selected_values = explode(';', $extra_data['extra_'.$field_details[1]]);
  3908. $extra_data['extra_'.$field_details[1]] = array();
  3909. // looping through the selected values and assigning the selected values to either the first or second select form
  3910. foreach ($selected_values as $key => $selected_value) {
  3911. if (array_key_exists($selected_value, $values[0])) {
  3912. $extra_data['extra_'.$field_details[1]]['extra_'.$field_details[1]] = $selected_value;
  3913. } else {
  3914. $extra_data['extra_'.$field_details[1]]['extra_'.$field_details[1].'*'] = $selected_value;
  3915. }
  3916. }
  3917. }
  3918. break;
  3919. case self::USER_FIELD_TYPE_DIVIDER:
  3920. $form->addElement('static', $field_details[1], '<br /><strong>'.$field_details[3].'</strong>');
  3921. break;
  3922. case self::USER_FIELD_TYPE_TAG:
  3923. //the magic should be here
  3924. $user_tags = UserManager::get_user_tags($user_id, $field_details[0]);
  3925. $tag_list = '';
  3926. if (is_array($user_tags) && count($user_tags) > 0) {
  3927. foreach ($user_tags as $tag) {
  3928. $tag_list .= '<option value="'.$tag['tag'].'" class="selected">'.$tag['tag'].'</option>';
  3929. }
  3930. }
  3931. $multi_select = '<select id="extra_'.$field_details[1].'" name="extra_'.$field_details[1].'">
  3932. '.$tag_list.'
  3933. </select>';
  3934. $form->addElement('label', $field_details[3], $multi_select);
  3935. $url = api_get_path(WEB_AJAX_PATH).'user_manager.ajax.php';
  3936. $complete_text = get_lang('StartToType');
  3937. //if cache is set to true the jquery will be called 1 time
  3938. $jquery_ready_content = <<<EOF
  3939. $("#extra_$field_details[1]").fcbkcomplete({
  3940. json_url: "$url?a=search_tags&field_id=$field_details[0]",
  3941. cache: false,
  3942. filter_case: true,
  3943. filter_hide: true,
  3944. complete_text:"$complete_text",
  3945. firstselected: true,
  3946. //onremove: "testme",
  3947. //onselect: "testme",
  3948. filter_selected: true,
  3949. newel: true
  3950. });
  3951. EOF;
  3952. break;
  3953. case self::USER_FIELD_TYPE_TIMEZONE:
  3954. $form->addElement('select', 'extra_'.$field_details[1], $field_details[3], api_get_timezones(), '');
  3955. if ($field_details[7] == 0)
  3956. $form->freeze('extra_'.$field_details[1]);
  3957. break;
  3958. case self::USER_FIELD_TYPE_SOCIAL_PROFILE:
  3959. // get the social network's favicon
  3960. $icon_path = UserManager::get_favicon_from_url($extra_data['extra_'.$field_details[1]], $field_details[4]);
  3961. // special hack for hi5
  3962. $leftpad = '1.7';
  3963. $top = '0.4';
  3964. $domain = parse_url($icon_path, PHP_URL_HOST);
  3965. if ($domain == 'www.hi5.com' or $domain == 'hi5.com') {
  3966. $leftpad = '3';
  3967. $top = '0';
  3968. }
  3969. // print the input field
  3970. $form->addElement(
  3971. 'text',
  3972. 'extra_'.$field_details[1],
  3973. $field_details[3],
  3974. array(
  3975. 'size' => 60,
  3976. 'style' => 'background-image: url(\''.$icon_path.'\'); background-repeat: no-repeat; background-position: 0.4em '.$top.'em; padding-left: '.$leftpad.'em; '
  3977. )
  3978. );
  3979. $form->applyFilter('extra_'.$field_details[1], 'stripslashes');
  3980. $form->applyFilter('extra_'.$field_details[1], 'trim');
  3981. if ($field_details[7] == 0)
  3982. $form->freeze('extra_'.$field_details[1]);
  3983. break;
  3984. }
  3985. }
  3986. $return = array();
  3987. $return['jquery_ready_content'] = $jquery_ready_content;
  3988. return $return;
  3989. }
  3990. /**
  3991. * @return array
  3992. */
  3993. static function get_user_field_types()
  3994. {
  3995. $types = array();
  3996. $types[self::USER_FIELD_TYPE_TEXT] = get_lang('FieldTypeText');
  3997. $types[self::USER_FIELD_TYPE_TEXTAREA] = get_lang('FieldTypeTextarea');
  3998. $types[self::USER_FIELD_TYPE_RADIO] = get_lang('FieldTypeRadio');
  3999. $types[self::USER_FIELD_TYPE_SELECT] = get_lang('FieldTypeSelect');
  4000. $types[self::USER_FIELD_TYPE_SELECT_MULTIPLE] = get_lang('FieldTypeSelectMultiple');
  4001. $types[self::USER_FIELD_TYPE_DATE] = get_lang('FieldTypeDate');
  4002. $types[self::USER_FIELD_TYPE_DATETIME] = get_lang('FieldTypeDatetime');
  4003. $types[self::USER_FIELD_TYPE_DOUBLE_SELECT] = get_lang('FieldTypeDoubleSelect');
  4004. $types[self::USER_FIELD_TYPE_DIVIDER] = get_lang('FieldTypeDivider');
  4005. $types[self::USER_FIELD_TYPE_TAG] = get_lang('FieldTypeTag');
  4006. $types[self::USER_FIELD_TYPE_TIMEZONE] = get_lang('FieldTypeTimezone');
  4007. $types[self::USER_FIELD_TYPE_SOCIAL_PROFILE] = get_lang('FieldTypeSocialProfile');
  4008. return $types;
  4009. }
  4010. /**
  4011. * @param int $user_id
  4012. */
  4013. static function add_user_as_admin($user_id)
  4014. {
  4015. $table_admin = Database :: get_main_table(TABLE_MAIN_ADMIN);
  4016. $user_id = intval($user_id);
  4017. if (!self::is_admin($user_id)) {
  4018. $sql = "INSERT INTO $table_admin SET user_id = '".$user_id."'";
  4019. Database::query($sql);
  4020. }
  4021. }
  4022. /**
  4023. * @param int $user_id
  4024. */
  4025. public static function remove_user_admin($user_id)
  4026. {
  4027. $table_admin = Database :: get_main_table(TABLE_MAIN_ADMIN);
  4028. $user_id = intval($user_id);
  4029. if (self::is_admin($user_id)) {
  4030. $sql = "DELETE FROM $table_admin WHERE user_id = '".$user_id."'";
  4031. Database::query($sql);
  4032. }
  4033. }
  4034. /**
  4035. * @param string $from
  4036. * @param string $to
  4037. */
  4038. public static function update_all_user_languages($from, $to)
  4039. {
  4040. $table_user = Database::get_main_table(TABLE_MAIN_USER);
  4041. $from = Database::escape_string($from);
  4042. $to = Database::escape_string($to);
  4043. if (!empty($to) && !empty($from)) {
  4044. $sql = "UPDATE $table_user SET language = '$to'
  4045. WHERE language = '$from'";
  4046. Database::query($sql);
  4047. }
  4048. }
  4049. }