usermanager.lib.php 220 KB

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