main_api.lib.php 156 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486
  1. <?php
  2. /* For licensing terms, see /license.txt */
  3. /**
  4. * This is a code library for Chamilo.
  5. * It is included by default in every Chamilo file (through including the global.inc.php)
  6. *
  7. * @package chamilo.library
  8. */
  9. /* CONSTANTS */
  10. //USER STATUS CONSTANTS
  11. /** global status of a user: student */
  12. define('STUDENT', 5);
  13. /** global status of a user: course manager */
  14. define('COURSEMANAGER', 1);
  15. /** global status of a user: session admin */
  16. define('SESSIONADMIN', 3);
  17. /** global status of a user: human ressource manager */
  18. define('DRH', 4);
  19. /** global status of a user: human ressource manager */
  20. define('ANONYMOUS', 6);
  21. /** global status of a user: low security, it's necessary for inserting data from the teacher */
  22. define('COURSEMANAGERLOWSECURITY', 10);
  23. // table of status
  24. $_status_list[STUDENT] = 'user';
  25. $_status_list[COURSEMANAGER] = 'teacher';
  26. $_status_list[SESSIONADMIN] = 'session_admin';
  27. $_status_list[DRH] = 'drh';
  28. $_status_list[ANONYMOUS] = 'anonymous';
  29. //COURSE VISIBILITY CONSTANTS
  30. /** only visible for course admin */
  31. define('COURSE_VISIBILITY_CLOSED', 0);
  32. /** only visible for users registered in the course*/
  33. define('COURSE_VISIBILITY_REGISTERED', 1);
  34. /** open for all registered users on the platform */
  35. define('COURSE_VISIBILITY_OPEN_PLATFORM', 2);
  36. /** open for the whole world */
  37. define('COURSE_VISIBILITY_OPEN_WORLD', 3);
  38. //SESSION VISIBILITY CONSTANTS
  39. define('SESSION_VISIBLE_READ_ONLY', 1);
  40. define('SESSION_VISIBLE', 2);
  41. define('SESSION_INVISIBLE',3);
  42. define('SUBSCRIBE_ALLOWED', 1);
  43. define('SUBSCRIBE_NOT_ALLOWED', 0);
  44. define('UNSUBSCRIBE_ALLOWED', 1);
  45. define('UNSUBSCRIBE_NOT_ALLOWED', 0);
  46. //CONSTANTS defining all tools, using the english version
  47. /*
  48. When you add a new tool you must add it into function api_get_tools_lists() too
  49. */
  50. define('TOOL_DOCUMENT', 'document');
  51. define('TOOL_THUMBNAIL', 'thumbnail');
  52. define('TOOL_HOTPOTATOES', 'hotpotatoes');
  53. define('TOOL_CALENDAR_EVENT', 'calendar_event');
  54. define('TOOL_LINK', 'link');
  55. define('TOOL_COURSE_DESCRIPTION', 'course_description');
  56. define('TOOL_SEARCH', 'search');
  57. define('TOOL_LEARNPATH', 'learnpath');
  58. define('TOOL_ANNOUNCEMENT', 'announcement');
  59. define('TOOL_FORUM', 'forum');
  60. define('TOOL_THREAD', 'thread');
  61. define('TOOL_POST', 'post');
  62. define('TOOL_DROPBOX', 'dropbox');
  63. define('TOOL_QUIZ', 'quiz');
  64. define('TOOL_USER', 'user');
  65. define('TOOL_GROUP', 'group');
  66. define('TOOL_BLOGS', 'blog_management'); // Smartblogs (Kevin Van Den Haute :: kevin@develop-it.be)
  67. define('TOOL_CHAT', 'chat');
  68. define('TOOL_CONFERENCE', 'conference');
  69. define('TOOL_STUDENTPUBLICATION', 'student_publication');
  70. define('TOOL_TRACKING', 'tracking');
  71. define('TOOL_HOMEPAGE_LINK', 'homepage_link');
  72. define('TOOL_COURSE_SETTING', 'course_setting');
  73. define('TOOL_BACKUP', 'backup');
  74. define('TOOL_COPY_COURSE_CONTENT', 'copy_course_content');
  75. define('TOOL_RECYCLE_COURSE', 'recycle_course');
  76. define('TOOL_COURSE_HOMEPAGE', 'course_homepage');
  77. define('TOOL_COURSE_RIGHTS_OVERVIEW', 'course_rights');
  78. define('TOOL_UPLOAD','file_upload');
  79. define('TOOL_COURSE_MAINTENANCE','course_maintenance');
  80. define('TOOL_VISIO','visio');
  81. define('TOOL_VISIO_CONFERENCE','visio_conference');
  82. define('TOOL_VISIO_CLASSROOM','visio_classroom');
  83. define('TOOL_SURVEY','survey');
  84. define('TOOL_WIKI','wiki');
  85. define('TOOL_GLOSSARY','glossary');
  86. define('TOOL_GRADEBOOK','gradebook');
  87. define('TOOL_NOTEBOOK','notebook');
  88. define('TOOL_ATTENDANCE','attendance');
  89. define('TOOL_COURSE_PROGRESS','course_progress');
  90. // CONSTANTS defining Chamilo interface sections
  91. define('SECTION_CAMPUS', 'mycampus');
  92. define('SECTION_COURSES', 'mycourses');
  93. define('SECTION_MYPROFILE', 'myprofile');
  94. define('SECTION_MYAGENDA', 'myagenda');
  95. define('SECTION_COURSE_ADMIN', 'course_admin');
  96. define('SECTION_PLATFORM_ADMIN', 'platform_admin');
  97. define('SECTION_MYGRADEBOOK', 'mygradebook');
  98. define('SECTION_TRACKING','session_my_space');
  99. define('SECTION_SOCIAL', 'social');
  100. define('SECTION_DASHBOARD', 'dashboard');
  101. // CONSTANT name for local authentication source
  102. define('PLATFORM_AUTH_SOURCE', 'platform');
  103. // CONSTANT defining the default HotPotatoes files directory
  104. define('DIR_HOTPOTATOES','/HotPotatoes_files');
  105. // event logs types
  106. define('LOG_COURSE_DELETE', 'course_deleted');
  107. define('LOG_COURSE_CREATE', 'course_created');
  108. define('LOG_USER_DELETE', 'user_deleted');
  109. define('LOG_USER_CREATE', 'user_created');
  110. define('LOG_SESSION_CREATE', 'session_created');
  111. define('LOG_SESSION_DELETE', 'session_deleted');
  112. define('LOG_SESSION_CATEGORY_CREATE', 'session_category_created');
  113. define('LOG_SESSION_CATEGORY_DELETE', 'session_category_deleted');
  114. define('LOG_CONFIGURATION_SETTINGS_CHANGE', 'settings_changed');
  115. define('LOG_SUBSCRIBE_USER_TO_COURSE', 'user_subscribed');
  116. define('LOG_UNSUBSCRIBE_USER_FROM_COURSE', 'user_unsubscribed');
  117. // event logs data types
  118. define('LOG_COURSE_CODE', 'course_code');
  119. define('LOG_USER_ID', 'user_id');
  120. define('LOG_SESSION_ID', 'session_id');
  121. define('LOG_SESSION_CATEGORY_ID', 'session_category_id');
  122. define('LOG_CONFIGURATION_SETTINGS_CATEGORY', 'settings_category');
  123. define('LOG_CONFIGURATION_SETTINGS_VARIABLE', 'settings_variable');
  124. // Specification for usernames:
  125. // 1. ASCII-letters, digits, "." (dot), "_" (underscore) are acceptable, 20 characters maximal length.
  126. // 2. Empty username is formally valid, but it is reserved for the anonymous user.
  127. define('USERNAME_MAX_LENGTH', 20);
  128. define('USERNAME_PURIFIER', '/[^0-9A-Za-z_\.]/');
  129. define('USERNAME_PURIFIER_SHALLOW', '/\s/');
  130. // Constants for detection some important PHP5 subversions.
  131. define('IS_PHP_52', !((float)PHP_VERSION < 5.2));
  132. define('IS_PHP_53', !((float)PHP_VERSION < 5.3));
  133. // This constant is a result of Windows OS detection, it has a boolean value:
  134. // true whether the server runs on Windows OS, false otherwise.
  135. define('IS_WINDOWS_OS', api_is_windows_os());
  136. // Checks for installed optional php-extensions.
  137. define('INTL_INSTALLED', function_exists('intl_get_error_code')); // intl extension (from PECL), it is installed by default as of PHP 5.3.0
  138. define('ICONV_INSTALLED', function_exists('iconv')); // iconv extension, for PHP5 on Windows it is installed by default.
  139. define('MBSTRING_INSTALLED', function_exists('mb_strlen')); // mbstring extension.
  140. define('DATE_TIME_INSTALLED', class_exists('DateTime')); // datetime extension, it is moved to the core as of PHP 5.2, see http://www.php.net/datetime
  141. // Patterns for processing paths. // Examples:
  142. define('REPEATED_SLASHES_PURIFIER', '/\/{2,}/'); // $path = preg_replace(REPEATED_SLASHES_PURIFIER, '/', $path);
  143. define('VALID_WEB_PATH', '/https?:\/\/[^\/]*(\/.*)?/i'); // $is_valid_path = preg_match(VALID_WEB_PATH, $path);
  144. define('VALID_WEB_SERVER_BASE', '/https?:\/\/[^\/]*/i'); // $new_path = preg_replace(VALID_WEB_SERVER_BASE, $new_base, $path);
  145. // Constants for api_get_path() and api_get_path_type(), etc. - registered path types.
  146. define('WEB_PATH', 'WEB_PATH');
  147. define('SYS_PATH', 'SYS_PATH');
  148. define('REL_PATH', 'REL_PATH');
  149. define('WEB_SERVER_ROOT_PATH', 'WEB_SERVER_ROOT_PATH');
  150. define('SYS_SERVER_ROOT_PATH', 'SYS_SERVER_ROOT_PATH');
  151. define('WEB_COURSE_PATH', 'WEB_COURSE_PATH');
  152. define('SYS_COURSE_PATH', 'SYS_COURSE_PATH');
  153. define('REL_COURSE_PATH', 'REL_COURSE_PATH');
  154. define('REL_CODE_PATH', 'REL_CODE_PATH');
  155. define('WEB_CODE_PATH', 'WEB_CODE_PATH');
  156. define('SYS_CODE_PATH', 'SYS_CODE_PATH');
  157. define('SYS_LANG_PATH', 'SYS_LANG_PATH');
  158. define('WEB_IMG_PATH', 'WEB_IMG_PATH');
  159. define('WEB_CSS_PATH', 'WEB_CSS_PATH');
  160. define('SYS_PLUGIN_PATH', 'SYS_PLUGIN_PATH');
  161. define('PLUGIN_PATH', 'SYS_PLUGIN_PATH'); // deprecated ?
  162. define('WEB_PLUGIN_PATH', 'WEB_PLUGIN_PATH');
  163. define('SYS_ARCHIVE_PATH', 'SYS_ARCHIVE_PATH');
  164. define('WEB_ARCHIVE_PATH', 'WEB_ARCHIVE_PATH');
  165. define('INCLUDE_PATH', 'INCLUDE_PATH');
  166. define('LIBRARY_PATH', 'LIBRARY_PATH');
  167. define('CONFIGURATION_PATH', 'CONFIGURATION_PATH');
  168. define('WEB_LIBRARY_PATH', 'WEB_LIBRARY_PATH');
  169. define('WEB_AJAX_PATH', 'WEB_AJAX_PATH');
  170. define('SYS_TEST_PATH', 'SYS_TEST_PATH');
  171. // Constants for requesting path conversion.
  172. define('TO_WEB', 'TO_WEB');
  173. define('TO_SYS', 'TO_SYS');
  174. define('TO_REL', 'TO_REL');
  175. // Paths to regidtered specific resource files (scripts, players, etc.)
  176. define('FLASH_PLAYER_AUDIO', '{FLASH_PLAYER_AUDIO}');
  177. define('FLASH_PLAYER_VIDEO', '{FLASH_PLAYER_VIDEO}');
  178. define('SCRIPT_SWFOBJECT', '{SCRIPT_SWFOBJECT}');
  179. define('SCRIPT_ASCIIMATHML', '{SCRIPT_ASCIIMATHML}');
  180. // Forcing PclZip library to use a custom temporary folder.
  181. define('PCLZIP_TEMPORARY_DIR', api_get_path(SYS_ARCHIVE_PATH));
  182. // Relations type with Human resources manager
  183. define('COURSE_RELATION_TYPE_RRHH', 1);
  184. define('SESSION_RELATION_TYPE_RRHH', 1);
  185. /* MAIN API EXTENSIONS */
  186. require_once dirname(__FILE__).'/internationalization.lib.php';
  187. /* PATHS & FILES - ROUTINES */
  188. /**
  189. * Returns a path to a certain resource within the Chamilo area, specifyed through a parameter.
  190. * Also, this function provides conversion between path types, in this case the input path points inside the Chamilo area too.
  191. *
  192. * See $_configuration['course_folder'] in the configuration.php to alter the WEB_COURSE_PATH and SYS_COURSE_PATH parameters.
  193. * @param string $type The requested path type (a defined constant), see the examples.
  194. * @param string $path (optional) A path which type is to be converted. Also, it may be a defined constant for a path.
  195. * This parameter has meaning when $type parameter has one of the following values: TO_WEB, TO_SYS, TO_REL. Otherwise it is ignored.
  196. * @return string The requested path or the converted path.
  197. *
  198. * A terminology note:
  199. * The defined constants used by this function contain the abbreviations WEB, REL, SYS with the following meaning for types:
  200. * WEB - an absolute URL (we often call it web-path),
  201. * example: http://www.mychamilo.org/chamilo/courses/COURSE01/document/lesson01.html;
  202. *
  203. * REL - represents a semi-absolute URL - a web-path, which is relative to the root web-path of the server, without server's base,
  204. * example: /chamilo/courses/COURSE01/document/lesson01.html;
  205. *
  206. * SYS - represents an absolute path inside the scope of server's file system,
  207. * /var/www/chamilo/courses/COURSE01/document/lesson01.html or
  208. * C:/Inetpub/wwwroot/chamilo/courses/COURSE01/document/lesson01.html.
  209. *
  210. * In some abstract sense we can consider these three path types as absolute.
  211. *
  212. * Notes about the current behaviour model:
  213. * 1. Windows back-slashes are converted to slashes in the result.
  214. * 2. A semi-absolute web-path is detected by its leading slash. On Linux systems, absolute system paths start with
  215. * a slash too, so an additional check about presense of leading system server base is implemented. For example, the function is
  216. * able to distinguish type difference between /var/www/chamilo/courses/ (SYS) and /chamilo/courses/ (REL).
  217. * 3. The function api_get_path() returns only these three types of paths, which in some sense are absolute. The function has
  218. * no a mechanism for processing relative web/system paths, such as: lesson01.html, ./lesson01.html, ../css/my_styles.css.
  219. * It has not been identified as needed yet.
  220. * 4. Also, resolving the meta-symbols "." and ".." withiin paths has not been implemented, it is to be identified as needed.
  221. *
  222. * @example
  223. * Assume that your server root is /var/www/ , Chamilo is installed in a subfolder chamilo/ and the URL of your campus is http://www.mychamilo.org
  224. * The other configuration paramaters have not been changed.
  225. *
  226. * This is how we can retireve mosth used paths, for common purpose:
  227. * api_get_path(REL_PATH) /chamilo/
  228. * api_get_path(REL_COURSE_PATH) /chamilo/courses/
  229. * api_get_path(REL_CODE_PATH) /chamilo/main/
  230. * api_get_path(SYS_SERVER_ROOT_PATH) /var/www/ - This is the physical folder where the system Chamilo has been placed. It is not always equal to $_SERVER['DOCUMENT_ROOT'].
  231. * api_get_path(SYS_PATH) /var/www/chamilo/
  232. * api_get_path(SYS_ARCHIVE_PATH) /var/www/chamilo/archive/
  233. * api_get_path(SYS_COURSE_PATH) /var/www/chamilo/courses/
  234. * api_get_path(SYS_CODE_PATH) /var/www/chamilo/main/
  235. * api_get_path(INCLUDE_PATH) /var/www/chamilo/main/inc/
  236. * api_get_path(LIBRARY_PATH) /var/www/chamilo/main/inc/lib/
  237. * api_get_path(CONFIGURATION_PATH) /var/www/chamilo/main/inc/conf/
  238. * api_get_path(SYS_LANG_PATH) /var/www/chamilo/main/lang/
  239. * api_get_path(SYS_PLUGIN_PATH) /var/www/chamilo/plugin/
  240. * api_get_path(SYS_TEST_PATH) /var/www/chamilo/tests/
  241. *
  242. * api_get_path(WEB_SERVER_ROOT_PATH) http://www.mychamilo.org/
  243. * api_get_path(WEB_PATH) http://www.mychamilo.org/chamilo/
  244. * api_get_path(WEB_COURSE_PATH) http://www.mychamilo.org/chamilo/courses/
  245. * api_get_path(WEB_CODE_PATH) http://www.mychamilo.org/chamilo/main/
  246. * api_get_path(WEB_PLUGIN_PATH) http://www.mychamilo.org/chamilo/plugin/
  247. * api_get_path(WEB_ARCHIVE_PATH) http://www.mychamilo.org/chamilo/archive/
  248. * api_get_path(WEB_IMG_PATH) http://www.mychamilo.org/chamilo/main/img/
  249. * api_get_path(WEB_CSS_PATH) http://www.mychamilo.org/chamilo/main/css/
  250. * api_get_path(WEB_LIBRARY_PATH) http://www.mychamilo.org/chamilo/main/inc/lib/
  251. *
  252. *
  253. * This is how we retrieve paths of "registerd" resource files (scripts, players, etc.):
  254. * api_get_path(TO_WEB, FLASH_PLAYER_AUDIO) http://www.mychamilo.org/chamilo/main/inc/lib/mediaplayer/player.swf
  255. * api_get_path(TO_WEB, FLASH_PLAYER_VIDEO) http://www.mychamilo.org/chamilo/main/inc/lib/mediaplayer/player.swf
  256. * api_get_path(TO_SYS, SCRIPT_SWFOBJECT) /var/www/chamilo/main/inc/lib/swfobject/swfobject.js
  257. * api_get_path(TO_REL, SCRIPT_ASCIIMATHML) /chamilo/main/inc/lib/asciimath/ASCIIMathML.js
  258. * ...
  259. *
  260. * We can convert arbitrary paths, that are not registered (no defined constant).
  261. * For guaranteed result, these paths should point inside the system Chamilo.
  262. * Some random examples:
  263. * api_get_path(TO_WEB, $_SERVER['REQUEST_URI'])
  264. * api_get_path(TO_SYS, $_SERVER['PHP_SELF'])
  265. * api_get_path(TO_REL, __FILE__)
  266. * ...
  267. */
  268. function api_get_path($path_type, $path = null) {
  269. static $paths = array(
  270. WEB_PATH => '',
  271. SYS_PATH => '',
  272. REL_PATH => '',
  273. WEB_SERVER_ROOT_PATH => '',
  274. SYS_SERVER_ROOT_PATH => '',
  275. WEB_COURSE_PATH => '',
  276. SYS_COURSE_PATH => '',
  277. REL_COURSE_PATH => '',
  278. REL_CODE_PATH => '',
  279. WEB_CODE_PATH => '',
  280. SYS_CODE_PATH => '',
  281. SYS_LANG_PATH => 'lang/',
  282. WEB_IMG_PATH => 'img/',
  283. WEB_CSS_PATH => 'css/',
  284. SYS_PLUGIN_PATH => 'plugin/',
  285. WEB_PLUGIN_PATH => 'plugin/',
  286. SYS_ARCHIVE_PATH => 'archive/',
  287. WEB_ARCHIVE_PATH => 'archive/',
  288. INCLUDE_PATH => 'inc/',
  289. LIBRARY_PATH => 'inc/lib/',
  290. CONFIGURATION_PATH => 'inc/conf/',
  291. WEB_LIBRARY_PATH => 'inc/lib/',
  292. WEB_AJAX_PATH => 'inc/ajax/',
  293. SYS_TEST_PATH => 'tests/'
  294. );
  295. static $resource_paths = array(
  296. FLASH_PLAYER_AUDIO => 'inc/lib/mediaplayer/player.swf',
  297. FLASH_PLAYER_VIDEO => 'inc/lib/mediaplayer/player.swf',
  298. SCRIPT_SWFOBJECT => 'inc/lib/swfobject/swfobject.js',
  299. SCRIPT_ASCIIMATHML => 'inc/lib/asciimath/ASCIIMathML.js'
  300. );
  301. static $is_this_function_initialized;
  302. static $server_base_web; // No trailing slash.
  303. static $server_base_sys; // No trailing slash.
  304. static $root_web;
  305. static $root_sys;
  306. static $root_rel;
  307. static $code_folder;
  308. static $course_folder;
  309. // Always load root_web modifications for multiple url features
  310. global $_configuration;
  311. //default $_configuration['root_web'] configuration
  312. $root_web = $_configuration['root_web'];
  313. // Configuration data for already installed system.
  314. $root_sys = $_configuration['root_sys'];
  315. $load_new_config = false;
  316. // To avoid that the api_get_access_url() function fails since global.inc.php also calls the main_api.lib.php
  317. if ($path_type == WEB_PATH) {
  318. if (isset($_configuration['access_url']) && $_configuration['access_url'] != 1) {
  319. //we look into the DB the function api_get_access_url
  320. $url_info = api_get_access_url($_configuration['access_url']);
  321. $root_web = $url_info['active'] == 1 ? $url_info['url'] : $_configuration['root_web'];
  322. $load_new_config = true;
  323. }
  324. }
  325. if (!$is_this_function_initialized) {
  326. global $_configuration;
  327. $root_rel = $_configuration['url_append'];
  328. $code_folder = $_configuration['code_append'];
  329. $course_folder = $_configuration['course_folder'];
  330. // Support for the installation process.
  331. // Developers might use the function api_get_path() directly or indirectly (this is difficult to be traced), at the moment when
  332. // configuration has not been created yet. This is why this function should be upgraded to return correct results in this case.
  333. if (defined('SYSTEM_INSTALLATION') && SYSTEM_INSTALLATION) {
  334. if (($pos = strpos(($requested_page_rel = api_get_self()), 'main/install')) !== false) {
  335. $root_rel = substr($requested_page_rel, 0, $pos);
  336. // See http://www.mediawiki.org/wiki/Manual:$wgServer
  337. $server_protocol = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') ? 'https' : 'http';
  338. $server_name =
  339. isset($_SERVER['SERVER_NAME']) ? $_SERVER['SERVER_NAME']
  340. : (isset($_SERVER['HOSTNAME']) ? $_SERVER['HOSTNAME']
  341. : (isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST']
  342. : (isset($_SERVER['SERVER_ADDR']) ? $_SERVER['SERVER_ADDR']
  343. : 'localhost')));
  344. if (isset($_SERVER['SERVER_PORT']) && !strpos($server_name, ':')
  345. && (($server_protocol == 'http'
  346. && $_SERVER['SERVER_PORT'] != 80 ) || ($server_protocol == 'https' && $_SERVER['SERVER_PORT'] != 443 ))) {
  347. $server_name .= ":" . $_SERVER['SERVER_PORT'];
  348. }
  349. $root_web = $server_protocol.'://'.$server_name.$root_rel;
  350. $root_sys = str_replace('\\', '/', realpath(dirname(__FILE__).'/../../../')).'/';
  351. $code_folder = 'main/';
  352. $course_folder = 'courses/';
  353. }
  354. // Here we give up, so we don't touch anything.
  355. }
  356. // Dealing with trailing slashes.
  357. $root_web = api_add_trailing_slash($root_web);
  358. $root_sys = api_add_trailing_slash($root_sys);
  359. $root_rel = api_add_trailing_slash($root_rel);
  360. $code_folder = api_add_trailing_slash($code_folder);
  361. $course_folder = api_add_trailing_slash($course_folder);
  362. // Web server base and system server base.
  363. $server_base_web = preg_replace('@'.$root_rel.'$@', '', $root_web); // No trailing slash.
  364. $server_base_sys = preg_replace('@'.$root_rel.'$@', '', $root_sys); // No trailing slash.
  365. // Initialization of a table taht contains common-purpose paths.
  366. $paths[WEB_PATH] = $root_web;
  367. $paths[SYS_PATH] = $root_sys;
  368. $paths[REL_PATH] = $root_rel;
  369. $paths[WEB_SERVER_ROOT_PATH] = $server_base_web.'/';
  370. $paths[SYS_SERVER_ROOT_PATH] = $server_base_sys.'/';
  371. $paths[WEB_COURSE_PATH] = $root_web.$course_folder;
  372. $paths[SYS_COURSE_PATH] = $root_sys.$course_folder;
  373. $paths[REL_COURSE_PATH] = $root_rel.$course_folder;
  374. $paths[REL_CODE_PATH] = $root_rel.$code_folder;
  375. $paths[WEB_CODE_PATH] = $root_web.$code_folder;
  376. $paths[SYS_CODE_PATH] = $root_sys.$code_folder;
  377. // Now we can switch into api_get_path() "terminology".
  378. $paths[SYS_LANG_PATH] = $paths[SYS_CODE_PATH].$paths[SYS_LANG_PATH];
  379. $paths[SYS_PLUGIN_PATH] = $paths[SYS_PATH].$paths[SYS_PLUGIN_PATH];
  380. $paths[SYS_ARCHIVE_PATH] = $paths[SYS_PATH].$paths[SYS_ARCHIVE_PATH];
  381. $paths[SYS_TEST_PATH] = $paths[SYS_PATH].$paths[SYS_TEST_PATH];
  382. $paths[WEB_CSS_PATH] = $paths[WEB_CODE_PATH].$paths[WEB_CSS_PATH];
  383. $paths[WEB_IMG_PATH] = $paths[WEB_CODE_PATH].$paths[WEB_IMG_PATH];
  384. $paths[WEB_LIBRARY_PATH] = $paths[WEB_CODE_PATH].$paths[WEB_LIBRARY_PATH];
  385. $paths[WEB_AJAX_PATH] = $paths[WEB_CODE_PATH].$paths[WEB_AJAX_PATH];
  386. $paths[WEB_PLUGIN_PATH] = $paths[WEB_PATH].$paths[WEB_PLUGIN_PATH];
  387. $paths[WEB_ARCHIVE_PATH] = $paths[WEB_PATH].$paths[WEB_ARCHIVE_PATH];
  388. $paths[INCLUDE_PATH] = $paths[SYS_CODE_PATH].$paths[INCLUDE_PATH];
  389. $paths[LIBRARY_PATH] = $paths[SYS_CODE_PATH].$paths[LIBRARY_PATH];
  390. $paths[CONFIGURATION_PATH] = $paths[SYS_CODE_PATH].$paths[CONFIGURATION_PATH];
  391. $is_this_function_initialized = true;
  392. } else {
  393. if ($load_new_config) {
  394. // Redefining variables to work well with the "multiple url" feature
  395. // All web paths need to be here
  396. $web_paths = array(
  397. WEB_PATH => '',
  398. WEB_SERVER_ROOT_PATH => '',
  399. WEB_COURSE_PATH => '',
  400. WEB_CODE_PATH => '',
  401. WEB_IMG_PATH => 'img/',
  402. WEB_CSS_PATH => 'css/',
  403. WEB_PLUGIN_PATH => 'plugin/',
  404. WEB_ARCHIVE_PATH => 'archive/',
  405. WEB_LIBRARY_PATH => 'inc/lib/',
  406. WEB_AJAX_PATH => 'inc/ajax/',
  407. );
  408. $root_web = api_add_trailing_slash($root_web);
  409. // Web server base and system server base.
  410. $server_base_web = preg_replace('@'.$root_rel.'$@', '', $root_web); // No trailing slash.
  411. // Redefine root webs
  412. $paths[WEB_PATH] = $root_web;
  413. $paths[WEB_SERVER_ROOT_PATH] = $server_base_web.'/';
  414. $paths[WEB_COURSE_PATH] = $root_web.$course_folder;
  415. $paths[WEB_CODE_PATH] = $root_web.$code_folder;
  416. $paths[WEB_IMG_PATH] = $paths[WEB_CODE_PATH].$web_paths[WEB_IMG_PATH];
  417. $paths[WEB_CSS_PATH] = $paths[WEB_CODE_PATH].$web_paths[WEB_CSS_PATH];
  418. $paths[WEB_PLUGIN_PATH] = $paths[WEB_PATH].$web_paths[WEB_PLUGIN_PATH];
  419. $paths[WEB_ARCHIVE_PATH] = $paths[WEB_PATH].$web_paths[WEB_ARCHIVE_PATH];
  420. $paths[WEB_LIBRARY_PATH] = $paths[WEB_CODE_PATH].$web_paths[WEB_LIBRARY_PATH];
  421. $paths[WEB_AJAX_PATH] = $paths[WEB_CODE_PATH].$web_paths[WEB_AJAX_PATH];
  422. }
  423. }
  424. // Shallow purification and validation of input parameters.
  425. $path_type = trim($path_type);
  426. $path = trim($path);
  427. if (empty($path_type)) {
  428. return null;
  429. }
  430. // Retrieving a common-purpose path.
  431. if (isset($paths[$path_type])) {
  432. return $paths[$path_type];
  433. }
  434. // Retrieving a specific resource path.
  435. if (isset($resource_paths[$path])) {
  436. switch ($path_type) {
  437. case TO_WEB:
  438. return $paths[WEB_CODE_PATH].$resource_paths[$path];
  439. case TO_SYS:
  440. return $paths[SYS_CODE_PATH].$resource_paths[$path];
  441. case TO_REL:
  442. return $paths[REL_CODE_PATH].$resource_paths[$path];
  443. default:
  444. return null;
  445. }
  446. }
  447. // Common-purpose paths as a second parameter - recognition.
  448. if (isset($paths[$path])) {
  449. $path = $paths[$path];
  450. }
  451. // Second purification.
  452. // Replacing Windows back slashes.
  453. $path = str_replace('\\', '/', $path);
  454. // Query strings sometimes mighth wrongly appear in non-URLs.
  455. // Let us check remove them from all types of paths.
  456. if (($pos = strpos($path, '?')) !== false) {
  457. $path = substr($path, 0, $pos);
  458. }
  459. // Detection of the input path type. Conversion to semi-absolute type ( /chamilo/main/inc/.... ).
  460. if (preg_match(VALID_WEB_PATH, $path)) {
  461. // A special case: When a URL points to the document download script directly, without
  462. // mod-rewrite translation, we have to translate it into an "ordinary" web path.
  463. // For example:
  464. // http://localhost/chamilo/main/document/download.php?doc_url=/image.png&cDir=/
  465. // becomes
  466. // http://localhost/chamilo/courses/TEST/document/image.png
  467. // TEST is a course directory name, so called "system course code".
  468. if (strpos($path, 'download.php') !== false) { // Fast detection first.
  469. $path = urldecode($path);
  470. if (preg_match('/(.*)main\/document\/download.php\?doc_url=\/(.*)&cDir=\/(.*)?/', $path, $matches)) {
  471. $sys_course_code =
  472. isset($_SESSION['_course']['sysCode']) // User is inside a course?
  473. ? $_SESSION['_course']['sysCode'] // Yes, then use course's directory name.
  474. : '{SYS_COURSE_CODE}'; // No, then use a fake code, it may be processed later.
  475. $path = $matches[1].'courses/'.$sys_course_code.'/document/'.str_replace('//', '/', $matches[3].'/'.$matches[2]);
  476. }
  477. }
  478. // Replacement of the present web server base with a slash '/'.
  479. $path = preg_replace(VALID_WEB_SERVER_BASE, '/', $path);
  480. } elseif (strpos($path, $server_base_sys) === 0) {
  481. $path = preg_replace('@^'.$server_base_sys.'@', '', $path);
  482. } elseif (strpos($path, '/') === 0) {
  483. // Leading slash - we assume that this path is semi-absolute (REL),
  484. // then path is left without furthes modifications.
  485. } else {
  486. return null; // Probably implementation of this case won't be needed.
  487. }
  488. // Path now is semi-absolute. It is convenient at this moment repeated slashes to be removed.
  489. $path = preg_replace(REPEATED_SLASHES_PURIFIER, '/', $path);
  490. // Path conversion to the requested type.
  491. switch ($path_type) {
  492. case TO_WEB:
  493. return $server_base_web.$path;
  494. case TO_SYS:
  495. return $server_base_sys.$path;
  496. case TO_REL:
  497. return $path;
  498. }
  499. return null;
  500. }
  501. /**
  502. * This function checks whether a given path points inside the system.
  503. * @param string $path The path to be tesed. It should be full path, web-absolute (WEB), semi-absolute (REL) or system-absolyte (SYS).
  504. * @return bool Returns true when the given path is inside the system, false otherwise.
  505. */
  506. function api_is_internal_path($path) {
  507. $path = str_replace('\\', '/', trim($path));
  508. if (empty($path)) {
  509. return false;
  510. }
  511. if (strpos($path, api_remove_trailing_slash(api_get_path(WEB_PATH))) === 0) {
  512. return true;
  513. }
  514. if (strpos($path, api_remove_trailing_slash(api_get_path(SYS_PATH))) === 0) {
  515. return true;
  516. }
  517. $server_base_web = api_remove_trailing_slash(api_get_path(REL_PATH));
  518. $server_base_web = empty($server_base_web) ? '/' : $server_base_web;
  519. if (strpos($path, $server_base_web) === 0) {
  520. return true;
  521. }
  522. return false;
  523. }
  524. /**
  525. * Adds to a given path a trailing slash if it is necessary (adds "/" character at the end of the string).
  526. * @param string $path The input path.
  527. * @return string Returns the modified path.
  528. */
  529. function api_add_trailing_slash($path) {
  530. return substr($path, -1) == '/' ? $path : $path.'/';
  531. }
  532. /**
  533. * Removes from a given path the trailing slash if it is necessary (removes "/" character from the end of the string).
  534. * @param string $path The input path.
  535. * @return string Returns the modified path.
  536. */
  537. function api_remove_trailing_slash($path) {
  538. return substr($path, -1) == '/' ? substr($path, 0, -1) : $path;
  539. }
  540. /* PROTECTION FUNCTIONS
  541. use these to protect your scripts */
  542. /**
  543. * Function used to protect a course script.
  544. * The function blocks access when
  545. * - there is no $_SESSION["_course"] defined; or
  546. * - $is_allowed_in_course is set to false (this depends on the course
  547. * visibility and user status).
  548. *
  549. * This is only the first proposal, test and improve!
  550. * @param boolean Option to print headers when displaying error message. Default: false
  551. * @return boolean True if the user has access to the current course or is out of a course context, false otherwise
  552. * @todo replace global variable
  553. * @author Roan Embrechts
  554. */
  555. function api_protect_course_script($print_headers = false) {
  556. global $is_allowed_in_course;
  557. if (!$is_allowed_in_course) {
  558. api_not_allowed($print_headers);
  559. return false;
  560. }
  561. return true;
  562. }
  563. /**
  564. * Function used to protect an admin script.
  565. * The function blocks access when the user has no platform admin rights.
  566. * This is only the first proposal, test and improve!
  567. *
  568. * @author Roan Embrechts
  569. */
  570. function api_protect_admin_script($allow_sessions_admins = false) {
  571. if (!api_is_platform_admin($allow_sessions_admins)) {
  572. include api_get_path(INCLUDE_PATH).'header.inc.php';
  573. api_not_allowed();
  574. return false;
  575. }
  576. return true;
  577. }
  578. /**
  579. * Function used to prevent anonymous users from accessing a script.
  580. *
  581. * @author Roan Embrechts
  582. */
  583. function api_block_anonymous_users() {
  584. global $_user;
  585. if (!(isset($_user['user_id']) && $_user['user_id']) || api_is_anonymous($_user['user_id'], true)) {
  586. require_once api_get_path(INCLUDE_PATH).'header.inc.php';
  587. api_not_allowed();
  588. return false;
  589. }
  590. return true;
  591. }
  592. /* ACCESSOR FUNCTIONS
  593. Don't access kernel variables directly, use these functions instead */
  594. /**
  595. * @return an array with the navigator name and version
  596. */
  597. function api_get_navigator() {
  598. $navigator = 'Unknown';
  599. $version = 0;
  600. if (strpos($_SERVER['HTTP_USER_AGENT'], 'Opera') !== false) {
  601. $navigator = 'Opera';
  602. list (, $version) = explode('Opera', $_SERVER['HTTP_USER_AGENT']);
  603. } elseif (strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE') !== false) {
  604. $navigator = 'Internet Explorer';
  605. list (, $version) = explode('MSIE', $_SERVER['HTTP_USER_AGENT']);
  606. } elseif (strpos($_SERVER['HTTP_USER_AGENT'], 'Gecko') !== false) {
  607. $navigator = 'Mozilla';
  608. list (, $version) = explode('; rv:', $_SERVER['HTTP_USER_AGENT']);
  609. } elseif (strpos($_SERVER['HTTP_USER_AGENT'], 'Netscape') !== false) {
  610. $navigator = 'Netscape';
  611. list (, $version) = explode('Netscape', $_SERVER['HTTP_USER_AGENT']);
  612. }
  613. // Added by Ivan Tcholakov, 23-AUG-2008.
  614. if (strpos($_SERVER['HTTP_USER_AGENT'], 'Konqueror') !== false) {
  615. $navigator = 'Konqueror';
  616. list (, $version) = explode('Konqueror', $_SERVER['HTTP_USER_AGENT']);
  617. }
  618. if (stripos($_SERVER['HTTP_USER_AGENT'], 'applewebkit') !== false) {
  619. $navigator = 'AppleWebKit';
  620. list (, $version) = explode('Version/', $_SERVER['HTTP_USER_AGENT']);
  621. }
  622. if (stripos($_SERVER['HTTP_USER_AGENT'], 'safari') !== false) {
  623. $navigator = 'Safari';
  624. list (, $version) = explode('Version/', $_SERVER['HTTP_USER_AGENT']);
  625. }
  626. //
  627. $version = doubleval($version);
  628. if (strpos($version, '.') === false) {
  629. $version = number_format(doubleval($version), 1);
  630. }
  631. return array ('name' => $navigator, 'version' => $version);
  632. }
  633. /**
  634. * @return True if user selfregistration is allowed, false otherwise.
  635. */
  636. function api_is_self_registration_allowed() {
  637. return isset($GLOBALS['allowSelfReg']) ? $GLOBALS['allowSelfReg'] : false;
  638. }
  639. /**
  640. * This function returns the id of the user which is stored in the $_user array.
  641. *
  642. * @example The function can be used to check if a user is logged in
  643. * if (api_get_user_id())
  644. * @return integer the id of the current user, 0 if is empty
  645. */
  646. function api_get_user_id() {
  647. return empty($GLOBALS['_user']['user_id']) ? 0 : intval($GLOBALS['_user']['user_id']);
  648. }
  649. /**
  650. * Gets the list of courses a specific user is subscribed to
  651. * @param int User ID
  652. * @param boolean Whether to get session courses or not - NOT YET IMPLEMENTED
  653. * @return array Array of courses in the form [0]=>('code'=>xxx,'db'=>xxx,'dir'=>xxx,'status'=>d)
  654. */
  655. function api_get_user_courses($userid, $fetch_session = true) {
  656. if ($userid != strval(intval($userid))) { return array(); } //get out if not integer
  657. $t_course = Database::get_main_table(TABLE_MAIN_COURSE);
  658. $t_course_user = Database::get_main_table(TABLE_MAIN_COURSE_USER);
  659. $t_session_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
  660. $t_session_user = Database::get_main_table(TABLE_MAIN_SESSION_USER);
  661. $t_session_course_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
  662. $sql_select_courses = "SELECT cc.code code, cc.db_name db, cc.directory dir, cu.status status
  663. FROM $t_course cc,
  664. $t_course_user cu
  665. WHERE cc.code = cu.course_code
  666. AND cu.user_id = '".$userid."' AND cu.relation_type<>".COURSE_RELATION_TYPE_RRHH." ";
  667. $result = Database::query($sql_select_courses);
  668. if ($result === false) { return array(); }
  669. while ($row = Database::fetch_array($result)) {
  670. // we only need the database name of the course
  671. $courses[] = $row;
  672. }
  673. return $courses;
  674. }
  675. /**
  676. * Formats user information into a standard array
  677. *
  678. * @param array Non-standard user array
  679. * @return array Standard user array
  680. */
  681. function _api_format_user($user) {
  682. $result = array();
  683. if (isset($user['firstname']) && isset($user['lastname'])) {
  684. $firstname = $user['firstname'];
  685. $lastname = $user['lastname'];
  686. } elseif (isset($user['firstName']) && isset($user['lastName'])) {
  687. $firstname = $user['firstName'];
  688. $lastname = $user['lastName'];
  689. }
  690. $result['firstname'] = $firstname;
  691. $result['lastname'] = $lastname;
  692. // Kept for historical reasons
  693. $result['firstName'] = $firstname;
  694. $result['lastName'] = $lastname;
  695. if(isset($user['email'])) {
  696. $result['mail'] = $user['email'];
  697. } else {
  698. $result['mail'] = $user['mail'];
  699. }
  700. $result['picture_uri'] = $user['picture_uri'];
  701. $result['user_id'] = intval($user['user_id']);
  702. $result['official_code'] = $user['official_code'];
  703. $result['status'] = $user['status'];
  704. $result['auth_source'] = $user['auth_source'];
  705. $result['username'] = $user['username'];
  706. $result['theme'] = $user['theme'];
  707. $result['language'] = $user['language'];
  708. if (!isset($user['lastLogin']) && !isset($user['last_login'])) {
  709. require_once api_get_path(LIBRARY_PATH).'tracking.lib.php';
  710. $timestamp = Tracking::get_last_connection_date($result['user_id'], false, true);
  711. // Convert the timestamp back into a datetime
  712. // NOTE: this timestamp has ALREADY been converted to the local timezone in the get_last_connection_date function
  713. $last_login = date('Y-m-d H:i:s', $timestamp);
  714. } else {
  715. if (isset($user['lastLogin'])) {
  716. $last_login = $user['lastLogin'];
  717. } else {
  718. $last_login = $user['last_login'];
  719. }
  720. }
  721. $result['last_login'] = $last_login;
  722. // Kept for historical reasons
  723. $result['lastLogin'] = $last_login;
  724. return $result;
  725. }
  726. /**
  727. * Finds all the information about a user. If no paramater is passed you find all the information about the current user.
  728. * @param $user_id (integer): the id of the user
  729. * @return $user_info (array): user_id, lastname, firstname, username, email, ...
  730. * @author Patrick Cool <patrick.cool@UGent.be>
  731. * @version 21 September 2004
  732. */
  733. function api_get_user_info($user_id = '') {
  734. global $tbl_user;
  735. if ($user_id == '') {
  736. return _api_format_user($GLOBALS['_user']);
  737. }
  738. $sql = "SELECT * FROM ".Database :: get_main_table(TABLE_MAIN_USER)." WHERE user_id='".Database::escape_string($user_id)."'";
  739. $result = Database::query($sql);
  740. if (Database::num_rows($result) > 0) {
  741. $result_array = Database::fetch_array($result);
  742. return _api_format_user($result_array);
  743. }
  744. return false;
  745. }
  746. /**
  747. * Finds all the information about a user from username instead of user id
  748. * @param $username (string): the username
  749. * @return $user_info (array): user_id, lastname, firstname, username, email, ...
  750. * @author Yannick Warnier <yannick.warnier@dokeos.com>
  751. */
  752. function api_get_user_info_from_username($username = '') {
  753. if (empty($username)) { return false; }
  754. global $tbl_user;
  755. $sql = "SELECT * FROM ".Database :: get_main_table(TABLE_MAIN_USER)." WHERE username='".Database::escape_string($username)."'";
  756. $result = Database::query($sql);
  757. if (Database::num_rows($result) > 0) {
  758. $result_array = Database::fetch_array($result);
  759. return _api_format_user($result_array);
  760. }
  761. return false;
  762. }
  763. /**
  764. * @TODO this function should be the real id (integer)
  765. * Returns the current course code (string)
  766. */
  767. function api_get_course_id() {
  768. return $GLOBALS['_cid'];
  769. }
  770. /**
  771. * Returns the current course id (integer)
  772. */
  773. function api_get_real_course_id() {
  774. return $GLOBALS['_real_cid'];
  775. }
  776. /**
  777. * Returns the current course directory
  778. *
  779. * This function relies on api_get_course_info()
  780. * @param string The course code - optional (takes it from session if not given)
  781. * @return string The directory where the course is located inside the Chamilo "courses" directory
  782. * @author Yannick Warnier <yannick.warnier@dokeos.com>
  783. */
  784. function api_get_course_path($course_code = null) {
  785. $info = !empty($course_code) ? api_get_course_info($course_code) : api_get_course_info();
  786. return $info['path'];
  787. }
  788. /**
  789. * Gets a course setting from the current course_setting table. Try always using integer values.
  790. * @param string The name of the setting we want from the table
  791. * @param string Optional: course code
  792. * @return mixed The value of that setting in that table. Return -1 if not found.
  793. */
  794. function api_get_course_setting($setting_name, $course_code = null) {
  795. if (!empty($course_code)) {
  796. $course_info = api_get_course_info($course_code);
  797. $table = Database::get_course_table(TABLE_COURSE_SETTING, $course_info['dbName']);
  798. } else {
  799. $table = Database::get_course_table(TABLE_COURSE_SETTING);
  800. }
  801. $setting_name = Database::escape_string($setting_name);
  802. $sql = "SELECT value FROM $table WHERE variable = '$setting_name'";
  803. $res = Database::query($sql);
  804. if (Database::num_rows($res) > 0) {
  805. $row = Database::fetch_array($res);
  806. return $row['value'];
  807. }
  808. return -1;
  809. }
  810. /**
  811. * Gets an anonymous user ID
  812. *
  813. * For some tools that need tracking, like the learnpath tool, it is necessary
  814. * to have a usable user-id to enable some kind of tracking, even if not
  815. * perfect. An anonymous ID is taken from the users table by looking for a
  816. * status of "6" (anonymous).
  817. * @return int User ID of the anonymous user, or O if no anonymous user found
  818. */
  819. function api_get_anonymous_id() {
  820. $table = Database::get_main_table(TABLE_MAIN_USER);
  821. $sql = "SELECT user_id FROM $table WHERE status = 6";
  822. $res = Database::query($sql);
  823. if (Database::num_rows($res) > 0) {
  824. $row = Database::fetch_array($res);
  825. //error_log('api_get_anonymous_id() returns '.$row['user_id'], 0);
  826. return $row['user_id'];
  827. }
  828. // No anonymous user was found
  829. return 0;
  830. }
  831. /**
  832. * Returns the cidreq parameter name + current course id
  833. */
  834. function api_get_cidreq() {
  835. return empty($GLOBALS['_cid']) ? '' : 'cidReq='.htmlspecialchars($GLOBALS['_cid']).(api_get_session_id() == 0 ? '' : '&id_session='.api_get_session_id());
  836. }
  837. /**
  838. * Returns the current course info array.
  839. * Note: this array is only defined if the user is inside a course.
  840. * Array elements:
  841. * ['name']
  842. * ['official_code']
  843. * ['sysCode']
  844. * ['path']
  845. * ['dbName']
  846. * ['dbNameGlu']
  847. * ['titular']
  848. * ['language']
  849. * ['extLink']['url' ]
  850. * ['extLink']['name']
  851. * ['categoryCode']
  852. * ['categoryName']
  853. *
  854. * Now if the course_code is given, the returned array gives info about that
  855. * particular course, not specially the current one.
  856. * @todo same behaviour as api_get_user_info so that api_get_course_id becomes absolete too
  857. */
  858. function api_get_course_info($course_code = null) {
  859. if (!empty($course_code)) {
  860. $course_code = Database::escape_string($course_code);
  861. $course_table = Database::get_main_table(TABLE_MAIN_COURSE);
  862. $course_cat_table = Database::get_main_table(TABLE_MAIN_CATEGORY);
  863. $sql = "SELECT course.*, course_category.code faCode, course_category.name faName
  864. FROM $course_table
  865. LEFT JOIN $course_cat_table
  866. ON course.category_code = course_category.code
  867. WHERE course.code = '$course_code'";
  868. $result = Database::query($sql);
  869. $_course = array();
  870. if (Database::num_rows($result) > 0) {
  871. global $_configuration;
  872. $cData = Database::fetch_array($result);
  873. $_course['id' ] = $cData['code' ];
  874. $_course['name' ] = $cData['title' ];
  875. $_course['official_code'] = $cData['visual_code' ]; // use in echo
  876. $_course['sysCode' ] = $cData['code' ]; // use as key in db
  877. $_course['path' ] = $cData['directory' ]; // use as key in path
  878. $_course['dbName' ] = $cData['db_name' ]; // use as key in db list
  879. $_course['dbNameGlu' ] = $_configuration['table_prefix'] . $cData['db_name'] . $_configuration['db_glue']; // use in all queries
  880. $_course['titular' ] = $cData['tutor_name' ];
  881. $_course['language' ] = $cData['course_language'];
  882. $_course['extLink' ]['url' ] = $cData['department_url' ];
  883. $_course['extLink' ]['name'] = $cData['department_name'];
  884. $_course['categoryCode' ] = $cData['faCode' ];
  885. $_course['categoryName' ] = $cData['faName' ];
  886. $_course['visibility' ] = $cData['visibility' ];
  887. $_course['subscribe_allowed'] = $cData['subscribe' ];
  888. $_course['unubscribe_allowed'] = $cData['unsubscribe' ];
  889. //the real_id is a integer is mandatory for feature implementations
  890. $_course['real_id' ] = $cData['id'];
  891. }
  892. return $_course;
  893. }
  894. global $_course;
  895. return $_course;
  896. }
  897. /**
  898. * Returns the current course info array.
  899. * Array elements:
  900. * ['name']
  901. * ['official_code']
  902. * ['sysCode']
  903. * ['path']
  904. * ['dbName']
  905. * ['dbNameGlu']
  906. * ['titular']
  907. * ['language']
  908. * ['extLink']['url' ]
  909. * ['extLink']['name']
  910. * ['categoryCode']
  911. * ['categoryName']
  912. * Now if the course_code is given, the returned array gives info about that
  913. * particular course, not specially the current one.
  914. */
  915. function api_get_course_info_by_id($id = null) {
  916. if (!empty($id)) {
  917. $id = intval($id);
  918. $course_table = Database::get_main_table(TABLE_MAIN_COURSE);
  919. $course_cat_table = Database::get_main_table(TABLE_MAIN_CATEGORY);
  920. $sql = "SELECT course.*, course_category.code faCode, course_category.name faName
  921. FROM $course_table
  922. LEFT JOIN $course_cat_table
  923. ON course.category_code = course_category.code
  924. WHERE course.id = $id";
  925. $result = Database::query($sql);
  926. $_course = array();
  927. if (Database::num_rows($result) > 0) {
  928. global $_configuration;
  929. $cData = Database::fetch_array($result);
  930. $_course['id' ] = $cData['code' ];
  931. //Added
  932. $_course['code' ] = $cData['code' ];
  933. $_course['name' ] = $cData['title' ];
  934. $_course['official_code'] = $cData['visual_code' ]; // use in echo
  935. $_course['sysCode' ] = $cData['code' ]; // use as key in db
  936. $_course['path' ] = $cData['directory' ]; // use as key in path
  937. $_course['dbName' ] = $cData['db_name' ]; // use as key in db list
  938. $_course['dbNameGlu' ] = $_configuration['table_prefix'] . $cData['db_name'] . $_configuration['db_glue']; // use in all queries
  939. $_course['titular' ] = $cData['tutor_name' ];
  940. $_course['language' ] = $cData['course_language'];
  941. $_course['extLink' ]['url' ] = $cData['department_url' ];
  942. $_course['extLink' ]['name'] = $cData['department_name'];
  943. $_course['categoryCode' ] = $cData['faCode' ];
  944. $_course['categoryName' ] = $cData['faName' ];
  945. $_course['visibility' ] = $cData['visibility' ];
  946. $_course['subscribe_allowed'] = $cData['subscribe' ];
  947. $_course['unubscribe_allowed'] = $cData['unsubscribe' ];
  948. $_course['real_id' ] = $cData['id'];
  949. $_course['db_name' ] = $cData['db_name' ];
  950. $_course['title' ] = $cData['title' ];
  951. }
  952. return $_course;
  953. }
  954. global $_course;
  955. return $_course;
  956. }
  957. /* SESSION MANAGEMENT */
  958. /**
  959. * Starts the Chamilo session.
  960. *
  961. * The default lifetime for session is set here. It is not possible to have it
  962. * as a database setting as it is used before the database connection has been made.
  963. * It is taken from the configuration file, and if it doesn't exist there, it is set
  964. * to 360000 seconds
  965. *
  966. * @author Olivier Brouckaert
  967. * @param string variable - the variable name to save into the session
  968. */
  969. function api_session_start($already_installed = true) {
  970. global $storeSessionInDb;
  971. global $_configuration;
  972. /* causes too many problems and is not configurable dynamically
  973. if ($already_installed) {
  974. $session_lifetime = 360000;
  975. if (isset($_configuration['session_lifetime'])) {
  976. $session_lifetime = $_configuration['session_lifetime'];
  977. }
  978. //session_set_cookie_params($session_lifetime,api_get_path(REL_PATH));
  979. }
  980. */
  981. if (is_null($storeSessionInDb)) {
  982. $storeSessionInDb = false;
  983. }
  984. if ($storeSessionInDb && function_exists('session_set_save_handler')) {
  985. require_once api_get_path(LIBRARY_PATH).'session_handler.class.php';
  986. $session_handler = new session_handler();
  987. @session_set_save_handler(array(& $session_handler, 'open'), array(& $session_handler, 'close'), array(& $session_handler, 'read'), array(& $session_handler, 'write'), array(& $session_handler, 'destroy'), array(& $session_handler, 'garbage'));
  988. }
  989. session_name('ch_sid');
  990. session_start();
  991. if (!isset($_SESSION['starttime'])) {
  992. $_SESSION['starttime'] = time();
  993. }
  994. if ($already_installed) {
  995. if (empty($_SESSION['checkDokeosURL'])) {
  996. $_SESSION['checkDokeosURL'] = api_get_path(WEB_PATH);
  997. //$_SESSION['session_expiry'] = time() + $session_lifetime; //useless at the moment
  998. } elseif ($_SESSION['checkDokeosURL'] != api_get_path(WEB_PATH)) {
  999. api_session_clear();
  1000. //$_SESSION['session_expiry'] = time() + $session_lifetime;
  1001. }
  1002. }
  1003. if ( isset($_SESSION['starttime']) && $_SESSION['starttime'] < time() - $_configuration['session_lifetime'] ) {
  1004. $_SESSION['starttime'] = time();
  1005. }
  1006. }
  1007. /**
  1008. * Saves a variable into the session
  1009. *
  1010. * BUG: function works only with global variables
  1011. *
  1012. * @author Olivier Brouckaert
  1013. * @param string variable - the variable name to save into the session
  1014. */
  1015. function api_session_register($variable) {
  1016. global $$variable;
  1017. $_SESSION[$variable] = $$variable;
  1018. }
  1019. /**
  1020. * Removes a variable from the session.
  1021. *
  1022. * @author Olivier Brouckaert
  1023. * @param string variable - the variable name to remove from the session
  1024. */
  1025. function api_session_unregister($variable) {
  1026. $variable = strval($variable);
  1027. if (isset($GLOBALS[$variable])) {
  1028. unset ($GLOBALS[$variable]);
  1029. }
  1030. if (isset($_SESSION[$variable])) {
  1031. unset($_SESSION[$variable]);
  1032. }
  1033. }
  1034. /**
  1035. * Clears the session
  1036. *
  1037. * @author Olivier Brouckaert
  1038. */
  1039. function api_session_clear() {
  1040. session_regenerate_id();
  1041. session_unset();
  1042. $_SESSION = array ();
  1043. }
  1044. /**
  1045. * Destroys the session
  1046. *
  1047. * @author Olivier Brouckaert
  1048. */
  1049. function api_session_destroy() {
  1050. session_unset();
  1051. $_SESSION = array();
  1052. session_destroy();
  1053. }
  1054. /* STRING MANAGEMENT */
  1055. /**
  1056. * Add a parameter to the existing URL. If this parameter already exists,
  1057. * just replace it with the new value
  1058. * @param string The URL
  1059. * @param string param=value string
  1060. * @param boolean Whether to filter XSS or not
  1061. * @return string The URL with the added parameter
  1062. */
  1063. function api_add_url_param($url, $param, $filter_xss = true) {
  1064. if (empty($param)) {
  1065. return $url;
  1066. }
  1067. if (strpos($url, '?') !== false) {
  1068. if ($param[0] != '&') {
  1069. $param = '&'.$param;
  1070. }
  1071. list (, $query_string) = explode('?', $url);
  1072. $param_list1 = explode('&', $param);
  1073. $param_list2 = explode('&', $query_string);
  1074. $param_list1_keys = $param_list1_vals = array();
  1075. foreach ($param_list1 as $key => $enreg) {
  1076. list ($param_list1_keys[$key], $param_list1_vals[$key]) = explode('=', $enreg);
  1077. }
  1078. $param_list1 = array ('keys' => $param_list1_keys, 'vals' => $param_list1_vals);
  1079. foreach ($param_list2 as $enreg) {
  1080. $enreg = explode('=', $enreg);
  1081. $key = array_search($enreg[0], $param_list1['keys']);
  1082. if (!is_null($key) && !is_bool($key)) {
  1083. $url = str_replace($enreg[0].'='.$enreg[1], $enreg[0].'='.$param_list1['vals'][$key], $url);
  1084. $param = str_replace('&'.$enreg[0].'='.$param_list1['vals'][$key], '', $param);
  1085. }
  1086. }
  1087. $url .= $param;
  1088. } else {
  1089. $url = $url.'?'.$param;
  1090. }
  1091. if ($filter_xss === true) {
  1092. $url = Security::remove_XSS(urldecode($url));
  1093. }
  1094. return $url;
  1095. }
  1096. /**
  1097. * Returns a difficult to guess password.
  1098. * @param int $length, the length of the password
  1099. * @return string the generated password
  1100. */
  1101. function api_generate_password($length = 8) {
  1102. $characters = 'abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ23456789';
  1103. if ($length < 2) {
  1104. $length = 2;
  1105. }
  1106. $password = '';
  1107. for ($i = 0; $i < $length; $i ++) {
  1108. $password .= $characters[rand() % strlen($characters)];
  1109. }
  1110. return $password;
  1111. }
  1112. /**
  1113. * Checks a password to see wether it is OK to use.
  1114. * @param string $password
  1115. * @return true if the password is acceptable, false otherwise
  1116. * Notes about what a password "OK to use" is:
  1117. * 1. The password should be at least 5 characters long.
  1118. * 2. Only English letters (uppercase or lowercase, it doesn't matter) and digits are allowed.
  1119. * 3. The password should contain at least 3 letters.
  1120. * 4. It should contain at least 2 digits.
  1121. * 5. It should not contain 3 or more consequent (according to ASCII table) characters.
  1122. */
  1123. function api_check_password($password) {
  1124. $password_length = api_strlen($password);
  1125. if ($password_length < 5) {
  1126. return false;
  1127. }
  1128. $password = api_strtolower($password);
  1129. $letters = 0;
  1130. $digits = 0;
  1131. $consequent_characters = 0;
  1132. $previous_character_code = 0;
  1133. for ($i = 0; $i < $password_length; $i ++) {
  1134. $current_character_code = api_ord(api_substr($password, $i, 1));
  1135. if ($i && abs($current_character_code - $previous_character_code) <= 1) {
  1136. $consequent_characters ++;
  1137. if ($consequent_characters == 3) {
  1138. return false;
  1139. }
  1140. } else {
  1141. $consequent_characters = 1;
  1142. }
  1143. if ($current_character_code >= 97 && $current_character_code <= 122) {
  1144. $letters ++;
  1145. } elseif ($current_character_code >= 48 && $current_character_code <= 57) {
  1146. $digits ++;
  1147. } else {
  1148. return false;
  1149. }
  1150. $previous_character_code = $current_character_code;
  1151. }
  1152. return ($letters >= 3 && $digits >= 2);
  1153. }
  1154. /**
  1155. * Clears the user ID from the session if it was the anonymous user. Generally
  1156. * used on out-of-tools pages to remove a user ID that could otherwise be used
  1157. * in the wrong context.
  1158. * This function is to be used in conjunction with the api_set_anonymous()
  1159. * function to simulate the user existence in case of an anonymous visit.
  1160. * @param bool database check switch - passed to api_is_anonymous()
  1161. * @return bool true if succesfully unregistered, false if not anonymous.
  1162. */
  1163. function api_clear_anonymous($db_check = false) {
  1164. global $_user;
  1165. if (api_is_anonymous($_user['user_id'], $db_check)) {
  1166. unset($_user['user_id']);
  1167. api_session_unregister('_uid');
  1168. return true;
  1169. }
  1170. return false;
  1171. }
  1172. /**
  1173. * Returns the status string corresponding to the status code
  1174. * @author Noel Dieschburg
  1175. * @param the int status code
  1176. */
  1177. function get_status_from_code($status_code) {
  1178. switch ($status_code) {
  1179. case STUDENT:
  1180. return get_lang('Student', '');
  1181. case TEACHER:
  1182. return get_lang('Teacher', '');
  1183. case COURSEMANAGER:
  1184. return get_lang('Manager', '');
  1185. case SESSIONADMIN:
  1186. return get_lang('SessionsAdmin', '');
  1187. case DRH:
  1188. return get_lang('Drh', '');
  1189. }
  1190. }
  1191. /* FAILURE MANAGEMENT */
  1192. /**
  1193. * The Failure Management module is here to compensate
  1194. * the absence of an 'exception' device in PHP 4.
  1195. */
  1196. /**
  1197. * $api_failureList - array containing all the failure recorded in order of arrival.
  1198. */
  1199. $api_failureList = array();
  1200. /**
  1201. * Fills a global array called $api_failureList
  1202. * This array collects all the failure occuring during the script runs
  1203. * The main purpose is allowing to manage the display messages externaly
  1204. * from the functions or objects. This strengthens encupsalation principle
  1205. *
  1206. * @author Hugues Peeters <peeters@ipm.ucl.ac.be>
  1207. * @param string $failure_type - the type of failure
  1208. * @global array $api_failureList
  1209. * @return bolean false to stay consistent with the main script
  1210. */
  1211. function api_set_failure($failure_type) {
  1212. global $api_failureList;
  1213. $api_failureList[] = $failure_type;
  1214. return false;
  1215. }
  1216. /**
  1217. * Sets the current user as anonymous if it hasn't been identified yet. This
  1218. * function should be used inside a tool only. The function api_clear_anonymous()
  1219. * acts in the opposite direction by clearing the anonymous user's data every
  1220. * time we get on a course homepage or on a neutral page (index, admin, my space)
  1221. * @return bool true if set user as anonymous, false if user was already logged in or anonymous id could not be found
  1222. */
  1223. function api_set_anonymous() {
  1224. global $_user;
  1225. if (!empty($_user['user_id'])) {
  1226. return false;
  1227. }
  1228. $user_id = api_get_anonymous_id();
  1229. if ($user_id == 0) {
  1230. return false;
  1231. }
  1232. api_session_unregister('_user');
  1233. $_user['user_id'] = $user_id;
  1234. $_user['is_anonymous'] = true;
  1235. api_session_register('_user');
  1236. $GLOBALS['_user'] = $_user;
  1237. return true;
  1238. }
  1239. /**
  1240. * Gets the last failure stored in $api_failureList;
  1241. *
  1242. * @author Hugues Peeters <hugues.peeters@claroline.net>
  1243. * @param void
  1244. * @return string - the last failure stored
  1245. */
  1246. function api_get_last_failure() {
  1247. global $api_failureList;
  1248. return $api_failureList[count($api_failureList) - 1];
  1249. }
  1250. /**
  1251. * Collects and manages failures occuring during script execution
  1252. * The main purpose is allowing to manage the display messages externaly
  1253. * from functions or objects. This strengthens encupsalation principle
  1254. *
  1255. * @author Hugues Peeters <hugues.peeters@claroline.net>
  1256. * @package dokeos.library
  1257. */
  1258. class api_failure {
  1259. // TODO: $api_failureList to be hidden from global scope and to be renamed according to our coding conventions.
  1260. /**
  1261. * IMPLEMENTATION NOTE : For now the $api_failureList list is set to the
  1262. * global scope, as PHP 4 is unable to manage static variable in class. But
  1263. * this feature is awaited in PHP 5. The class is already written to minize
  1264. * the change when static class variable will be possible. And the API won't
  1265. * change.
  1266. */
  1267. public $api_failureList = array();
  1268. /**
  1269. * Piles the last failure in the failure list
  1270. *
  1271. * @author Hugues Peeters <peeters@ipm.ucl.ac.be>
  1272. * @param string $failure_type - the type of failure
  1273. * @global array $api_failureList
  1274. * @return bolean false to stay consistent with the main script
  1275. */
  1276. function set_failure($failure_type) {
  1277. global $api_failureList;
  1278. $api_failureList[] = $failure_type;
  1279. return false;
  1280. }
  1281. /**
  1282. * Gets the last failure stored
  1283. *
  1284. * @author Hugues Peeters <hugues.peeters@claroline.net>
  1285. * @param void
  1286. * @return string - the last failure stored
  1287. */
  1288. function get_last_failure() {
  1289. global $api_failureList;
  1290. if (count($api_failureList) == 0) { return ''; }
  1291. return $api_failureList[count($api_failureList) - 1];
  1292. }
  1293. }
  1294. /* CONFIGURATION SETTINGS */
  1295. /**
  1296. * Gets the current Chamilo (not PHP/cookie) session ID, if active
  1297. * @return int O if no active session, the session ID otherwise
  1298. */
  1299. function api_get_session_id() {
  1300. return empty($_SESSION['id_session']) ? 0 : (int)$_SESSION['id_session'];
  1301. }
  1302. /**
  1303. * Gets the current or given session name
  1304. * @param int Session ID (optional)
  1305. * @return string The session name, or null if unfound
  1306. */
  1307. function api_get_session_name($session_id) {
  1308. if (empty($session_id)) {
  1309. $session_id = api_get_session_id();
  1310. if (empty($session_id)) { return null; }
  1311. }
  1312. $t = Database::get_main_table(TABLE_MAIN_SESSION);
  1313. $s = "SELECT name FROM $t WHERE id = ".(int)$session_id;
  1314. $r = Database::query($s);
  1315. $c = Database::num_rows($r);
  1316. if ($c > 0) {
  1317. //technically, there can be only one, but anyway we take the first
  1318. $rec = Database::fetch_array($r);
  1319. return $rec['name'];
  1320. }
  1321. return null;
  1322. }
  1323. /**
  1324. * Gets the session info by id
  1325. * @param int Session ID
  1326. * @return array information of the session
  1327. */
  1328. function api_get_session_info($session_id) {
  1329. $data = array();
  1330. if (!empty($session_id)) {
  1331. $sesion_id = intval(Database::escape_string($session_id));
  1332. $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
  1333. $sql = "SELECT * FROM $tbl_session WHERE id = $session_id";
  1334. $result = Database::query($sql);
  1335. if (Database::num_rows($result)>0) {
  1336. $data = Database::fetch_array($result, 'ASSOC');
  1337. }
  1338. }
  1339. return $data;
  1340. }
  1341. /**
  1342. * Gets the session visibility by session id
  1343. * @param int session id
  1344. * @return int 0 = session still available, SESSION_VISIBLE_READ_ONLY = 1, SESSION_VISIBLE = 2, SESSION_INVISIBLE = 3
  1345. */
  1346. function api_get_session_visibility($session_id) {
  1347. $visibility = 0; //means that the session is still available
  1348. if (!empty($session_id)) {
  1349. $sesion_id = intval(Database::escape_string($session_id));
  1350. $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
  1351. $is_coach = api_is_coach();
  1352. $condition_date_end = "";
  1353. if ($is_coach) {
  1354. $condition_date_end = " AND (CURDATE() > (SELECT adddate(date_end,nb_days_access_after_end) FROM $tbl_session WHERE id = $session_id) AND date_end != '0000-00-00') ";
  1355. } else {
  1356. $condition_date_end = " AND (date_end < CURDATE() AND date_end != '0000-00-00') ";
  1357. }
  1358. $sql = "SELECT visibility FROM $tbl_session
  1359. WHERE id = $session_id $condition_date_end "; // session is old and is not unlimited
  1360. $result = Database::query($sql);
  1361. if (Database::num_rows($result)>0) {
  1362. $row = Database::fetch_array($result, 'ASSOC');
  1363. $visibility = $row['visibility'];
  1364. } else {
  1365. $visibility = 0;
  1366. }
  1367. }
  1368. return $visibility;
  1369. }
  1370. /**
  1371. * Gets the visibility of an session of a course that a student have
  1372. * @param int session id
  1373. * @param string Chamilo course code
  1374. * @param int user id
  1375. * @return int 0= Session available (in date), SESSION_VISIBLE_READ_ONLY = 1, SESSION_VISIBLE = 2, SESSION_INVISIBLE = 3
  1376. */
  1377. function api_get_session_visibility_by_user($session_id, $course_code, $user_id) {
  1378. $visibility = 0; // Means that the session is still available.
  1379. if (!empty($session_id) && !empty($user_id)){
  1380. $sesion_id = intval(Database::escape_string($session_id));
  1381. $user_id = intval(Database::escape_string($user_id));
  1382. $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION_REL_COURSE_REL_USER);
  1383. $sql = "SELECT visibility FROM $tbl_session
  1384. WHERE id_session = $session_id AND id_user = $user_id AND course_code = '$course_code'"; // session old
  1385. $result = Database::query($sql);
  1386. if (Database::num_rows($result) > 0) {
  1387. $row = Database::fetch_array($result, 'ASSOC');
  1388. $visibility = $row['visibility'];
  1389. } else {
  1390. $visibility = 0;
  1391. }
  1392. }
  1393. return $visibility;
  1394. }
  1395. /**
  1396. * This function validates if the resource belongs to a session and returns an image
  1397. * @param int session id
  1398. * @param int status id
  1399. * @return string image session
  1400. */
  1401. function api_get_session_image($session_id, $status_id) {
  1402. //validacion when belongs to a session
  1403. $session_id = (int)$session_id;
  1404. $session_img = '';
  1405. if ((int)$status_id != 5) { //check whether is not a student
  1406. if ($session_id > 0) {
  1407. $session_img = "&nbsp;".Display::return_icon('star.png', get_lang('ResourceSession'), array('align' => 'absmiddle'));
  1408. }
  1409. }
  1410. return $session_img;
  1411. }
  1412. /**
  1413. * This function add an additional condition according to the session of the course
  1414. * @param int session id
  1415. * @param bool optional, true if more than one condition false if the only condition in the query
  1416. * @param bool optional, true if condition is only with session_id = current session id, false if condition is with 0 else
  1417. * @return string condition of the session
  1418. */
  1419. function api_get_session_condition($session_id, $and = true, $with_base_content = false) {
  1420. $session_id = intval($session_id);
  1421. //condition to show resources by session
  1422. $condition_session = '';
  1423. $condition_add = $and == false ? " WHERE " : " AND ";
  1424. if ($with_base_content) {
  1425. $condition_session = $condition_add." (session_id = $session_id OR session_id = 0) ";
  1426. } else {
  1427. $condition_session = $condition_add." session_id = $session_id ";
  1428. }
  1429. return $condition_session;
  1430. }
  1431. /**
  1432. * This function returns information about coachs from a course in session
  1433. * @param int - optional, session id
  1434. * @param string - optional, course code
  1435. * @return array - array containing user_id, lastname, firstname, username.
  1436. */
  1437. function api_get_coachs_from_course($session_id=0,$course_code='') {
  1438. if (!empty($session_id)) {
  1439. $session_id = intval($session_id);
  1440. } else {
  1441. $session_id = api_get_session_id();
  1442. }
  1443. if (!empty($course_code)) {
  1444. $course_code = Database::escape_string($course_code);
  1445. } else {
  1446. $course_code = api_get_course_id();
  1447. }
  1448. $tbl_user = Database :: get_main_table(TABLE_MAIN_USER);
  1449. $tbl_session_course_user = Database :: get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
  1450. $coaches = array();
  1451. $sql = "SELECT u.user_id,u.lastname,u.firstname,u.username FROM $tbl_user u,$tbl_session_course_user scu
  1452. WHERE u.user_id = scu.id_user AND scu.id_session = '$session_id' AND scu.course_code = '$course_code' AND scu.status = 2";
  1453. $rs = Database::query($sql);
  1454. if (Database::num_rows($rs) > 0) {
  1455. while ($row = Database::fetch_array($rs)) {
  1456. $coaches[] = $row;
  1457. }
  1458. return $coaches;
  1459. } else {
  1460. return false;
  1461. }
  1462. }
  1463. /**
  1464. * Returns the value of a setting from the web-adjustable admin config settings.
  1465. *
  1466. * WARNING true/false are stored as string, so when comparing you need to check e.g.
  1467. * if (api_get_setting('show_navigation_menu') == 'true') //CORRECT
  1468. * instead of
  1469. * if (api_get_setting('show_navigation_menu') == true) //INCORRECT
  1470. * @param string The variable name
  1471. * @param string The subkey (sub-variable) if any. Defaults to NULL
  1472. * @author René Haentjens
  1473. * @author Bart Mollet
  1474. */
  1475. function api_get_setting($variable, $key = null) {
  1476. global $_setting;
  1477. return is_null($key) ? (!empty($_setting[$variable]) ? $_setting[$variable] : null) : $_setting[$variable][$key];
  1478. }
  1479. /**
  1480. * Returns an escaped version of $_SERVER['PHP_SELF'] to avoid XSS injection
  1481. * @return string Escaped version of $_SERVER['PHP_SELF']
  1482. */
  1483. function api_get_self() {
  1484. return htmlentities($_SERVER['PHP_SELF']);
  1485. }
  1486. /* USER PERMISSIONS */
  1487. /**
  1488. * Checks whether current user is a platform administrator
  1489. * @return boolean True if the user has platform admin rights,
  1490. * false otherwise.
  1491. * @see usermanager::is_admin(user_id) for a user-id specific function
  1492. */
  1493. function api_is_platform_admin($allow_sessions_admins = false) {
  1494. if ($_SESSION['is_platformAdmin']) {
  1495. return true;
  1496. }
  1497. global $_user;
  1498. return $allow_sessions_admins && $_user['status'] == SESSIONADMIN;
  1499. }
  1500. /**
  1501. * Checks whether current user is allowed to create courses
  1502. * @return boolean True if the user has course creation rights,
  1503. * false otherwise.
  1504. */
  1505. function api_is_allowed_to_create_course() {
  1506. return $_SESSION['is_allowedCreateCourse'];
  1507. }
  1508. /**
  1509. * Checks whether the current user is a course administrator
  1510. * @return boolean True if current user is a course administrator
  1511. */
  1512. function api_is_course_admin() {
  1513. return $_SESSION['is_courseAdmin'];
  1514. }
  1515. /**
  1516. * Checks whether the current user is a course coach
  1517. * @return bool True if current user is a course coach
  1518. */
  1519. function api_is_course_coach() {
  1520. return $_SESSION['is_courseCoach'];
  1521. }
  1522. /**
  1523. * Checks whether the current user is a course tutor
  1524. * @return bool True if current user is a course tutor
  1525. */
  1526. function api_is_course_tutor() {
  1527. return $_SESSION['is_courseTutor'];
  1528. }
  1529. /**
  1530. * Checks whether the current user is a course or session coach
  1531. * @params int - optional, session id
  1532. * @params string - optional, course code
  1533. * @return boolean True if current user is a course or session coach
  1534. */
  1535. function api_is_coach($session_id = 0, $course_code = '') {
  1536. global $_user;
  1537. global $sessionIsCoach;
  1538. if (!empty($session_id)) {
  1539. $session_id = intval($session_id);
  1540. } else {
  1541. $session_id = api_get_session_id();
  1542. }
  1543. if (!empty($course_code)) {
  1544. $course_code = Database::escape_string($course_code);
  1545. } else {
  1546. $course_code = api_get_course_id();
  1547. }
  1548. $sql = "SELECT DISTINCT id, name, date_start, date_end
  1549. FROM session
  1550. INNER JOIN session_rel_course_rel_user session_rc_ru
  1551. ON session_rc_ru.id_user = '".Database::escape_string($_user['user_id'])."'
  1552. WHERE session_rc_ru.course_code = '$course_code' AND session_rc_ru.status = 2 AND session_rc_ru.id_session = '$session_id'
  1553. ORDER BY date_start, date_end, name";
  1554. $result = Database::query($sql);
  1555. $sessionIsCoach = Database::store_result($result);
  1556. $sql = "SELECT DISTINCT id, name, date_start, date_end
  1557. FROM session
  1558. WHERE session.id_coach = '".Database::escape_string($_user['user_id'])."'
  1559. AND id = '$session_id'
  1560. ORDER BY date_start, date_end, name";
  1561. $result = Database::query($sql);
  1562. $sessionIsCoach = array_merge($sessionIsCoach , Database::store_result($result));
  1563. return (count($sessionIsCoach) > 0);
  1564. }
  1565. /**
  1566. * Checks whether the current user is a session administrator
  1567. * @return boolean True if current user is a course administrator
  1568. */
  1569. function api_is_session_admin() {
  1570. global $_user;
  1571. return $_user['status'] == SESSIONADMIN;
  1572. }
  1573. /**
  1574. * Checks whether the current user is a human resources manager
  1575. * @return boolean True if current user is a human resources manager
  1576. */
  1577. function api_is_drh() {
  1578. global $_user;
  1579. return $_user['status'] == DRH;
  1580. }
  1581. /**
  1582. * This function checks whether a session is assigned into a category
  1583. * @param int - session id
  1584. * @param string - category name
  1585. * @return bool - true if is found, otherwise false
  1586. */
  1587. function api_is_session_in_category($session_id, $category_name) {
  1588. $session_id = intval($session_id);
  1589. $category_name = Database::escape_string($category_name);
  1590. $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
  1591. $tbl_session_category = Database::get_main_table(TABLE_MAIN_SESSION_CATEGORY);
  1592. $sql = "select 1 FROM $tbl_session WHERE $session_id IN (SELECT s.id FROM $tbl_session s, $tbl_session_category sc WHERE s.session_category_id = sc.id AND sc.name LIKE '%$category_name' )";
  1593. $rs = Database::query($sql);
  1594. if (Database::num_rows($rs) > 0) {
  1595. return true;
  1596. } else {
  1597. return false;
  1598. }
  1599. }
  1600. /* DISPLAY OPTIONS
  1601. student view, title, message boxes,... */
  1602. /**
  1603. * Displays the title of a tool.
  1604. * Normal use: parameter is a string:
  1605. * api_display_tool_title("My Tool")
  1606. *
  1607. * Optionally, there can be a subtitle below
  1608. * the normal title, and / or a supra title above the normal title.
  1609. *
  1610. * e.g. supra title:
  1611. * group
  1612. * GROUP PROPERTIES
  1613. *
  1614. * e.g. subtitle:
  1615. * AGENDA
  1616. * calender & events tool
  1617. *
  1618. * @author Hugues Peeters <hugues.peeters@claroline.net>
  1619. * @param mixed $title_element - it could either be a string or an array
  1620. * containing 'supraTitle', 'mainTitle',
  1621. * 'subTitle'
  1622. * @return void
  1623. */
  1624. function api_display_tool_title($title_element) {
  1625. if (is_string($title_element)) {
  1626. $tit = $title_element;
  1627. unset ($title_element);
  1628. $title_element['mainTitle'] = $tit;
  1629. }
  1630. echo '<h3>';
  1631. if (!empty($title_element['supraTitle'])) {
  1632. echo '<small>'.$title_element['supraTitle'].'</small><br />';
  1633. }
  1634. if (!empty($title_element['mainTitle'])) {
  1635. echo $title_element['mainTitle'];
  1636. }
  1637. if (!empty($title_element['subTitle'])) {
  1638. echo '<br /><small>'.$title_element['subTitle'].'</small>';
  1639. }
  1640. echo '</h3>';
  1641. }
  1642. /**
  1643. * Displays options for switching between student view and course manager view
  1644. *
  1645. * Changes in version 1.2 (Patrick Cool)
  1646. * Student view switch now behaves as a real switch. It maintains its current state until the state
  1647. * is changed explicitly
  1648. *
  1649. * Changes in version 1.1 (Patrick Cool)
  1650. * student view now works correctly in subfolders of the document tool
  1651. * student view works correctly in the new links tool
  1652. *
  1653. * Example code for using this in your tools:
  1654. * //if ( $is_courseAdmin && api_get_setting('student_view_enabled') == 'true' )
  1655. * //{
  1656. * // display_tool_view_option($isStudentView);
  1657. * //}
  1658. * //and in later sections, use api_is_allowed_to_edit()
  1659. *
  1660. * @author Roan Embrechts
  1661. * @author Patrick Cool
  1662. * @version 1.2
  1663. * @todo rewrite code so it is easier to understand
  1664. */
  1665. function api_display_tool_view_option() {
  1666. if (api_get_setting('student_view_enabled') != 'true') {
  1667. return '';
  1668. }
  1669. $output_string = '';
  1670. $sourceurl = '';
  1671. $is_framed = false;
  1672. // Exceptions apply for all multi-frames pages
  1673. if (strpos($_SERVER['REQUEST_URI'], 'chat/chat_banner.php') !== false) { // The chat is a multiframe bit that doesn't work too well with the student_view, so do not show the link
  1674. $is_framed = true;
  1675. return '';
  1676. }
  1677. // Uncomment to remove student view link from document view page
  1678. if (strpos($_SERVER['REQUEST_URI'], 'document/headerpage.php') !== false) {
  1679. $sourceurl = str_replace('document/headerpage.php', 'document/showinframes.php', $_SERVER['REQUEST_URI']);
  1680. //showinframes doesn't handle student view anyway...
  1681. //return '';
  1682. $is_framed = true;
  1683. }
  1684. // Uncomment to remove student view link from document view page
  1685. if (strpos($_SERVER['REQUEST_URI'], 'newscorm/lp_header.php') !== false) {
  1686. if (empty($_GET['lp_id'])) {
  1687. return '';
  1688. }
  1689. $sourceurl = substr($_SERVER['REQUEST_URI'], 0, strpos($_SERVER['REQUEST_URI'], '?'));
  1690. $sourceurl = str_replace('newscorm/lp_header.php', 'newscorm/lp_controller.php?'.api_get_cidreq().'&action=view&lp_id='.intval($_GET['lp_id']).'&isStudentView='.($_SESSION['studentview']=='studentview' ? 'false' : 'true'), $sourceurl);
  1691. //showinframes doesn't handle student view anyway...
  1692. //return '';
  1693. $is_framed = true;
  1694. }
  1695. // Check whether the $_SERVER['REQUEST_URI'] contains already url parameters (thus a questionmark)
  1696. if (!$is_framed) {
  1697. if (strpos($_SERVER['REQUEST_URI'], '?') === false) {
  1698. $sourceurl = api_get_self().'?'.api_get_cidreq();
  1699. } else {
  1700. $sourceurl = $_SERVER['REQUEST_URI'];
  1701. //$sourceurl = str_replace('&', '&amp;', $sourceurl);
  1702. }
  1703. }
  1704. if (!empty($_SESSION['studentview'])) {
  1705. if ($_SESSION['studentview'] == 'studentview') {
  1706. // We have to remove the isStudentView=true from the $sourceurl
  1707. $sourceurl = str_replace('&isStudentView=true', '', $sourceurl);
  1708. $sourceurl = str_replace('&isStudentView=false', '', $sourceurl);
  1709. $output_string .= '<a href="'.$sourceurl.'&isStudentView=false" target="_self">'.get_lang('CourseManagerview').'</a>';
  1710. } elseif ($_SESSION['studentview'] == 'teacherview') {
  1711. // Switching to teacherview
  1712. $sourceurl = str_replace('&isStudentView=true', '', $sourceurl);
  1713. $sourceurl = str_replace('&isStudentView=false', '', $sourceurl);
  1714. $output_string .= '<a href="'.$sourceurl.'&isStudentView=true" target="_self">'.get_lang('StudentView').'</a>';
  1715. }
  1716. } else {
  1717. $output_string .= '<a href="'.$sourceurl.'&isStudentView=true" target="_self">'.get_lang('StudentView').'</a>';
  1718. }
  1719. echo $output_string;
  1720. }
  1721. /**
  1722. * Displays the contents of an array in a messagebox.
  1723. * @param array $info_array An array with the messages to show
  1724. */
  1725. function api_display_array($info_array) {
  1726. if(is_array($info_array)) {
  1727. foreach ($info_array as $element) {
  1728. $message .= $element.'<br />';
  1729. }
  1730. }
  1731. Display :: display_normal_message($message);
  1732. }
  1733. /**
  1734. * Displays debug info
  1735. * @param string $debug_info The message to display
  1736. * @author Roan Embrechts
  1737. * @version 1.1, March 2004
  1738. */
  1739. function api_display_debug_info($debug_info) {
  1740. $message = '<i>Debug info</i><br />';
  1741. $message .= $debug_info;
  1742. Display :: display_normal_message($message);
  1743. }
  1744. // TODO: This is for the permission section.
  1745. /**
  1746. * Function that removes the need to directly use is_courseAdmin global in
  1747. * tool scripts. It returns true or false depending on the user's rights in
  1748. * this particular course.
  1749. * Optionally checking for tutor and coach roles here allows us to use the
  1750. * student_view feature altogether with these roles as well.
  1751. * @param bool Whether to check if the user has the tutor role
  1752. * @param bool Whether to check if the user has the coach role
  1753. * @param bool Whether to check if the user has the session coach role
  1754. *
  1755. * @author Roan Embrechts
  1756. * @author Patrick Cool
  1757. * @version 1.1, February 2004
  1758. * @return boolean, true: the user has the rights to edit, false: he does not
  1759. */
  1760. function api_is_allowed_to_edit($tutor = false, $coach = false, $session_coach = false) {
  1761. $my_session_id = api_get_session_id();
  1762. $is_allowed_coach_to_edit = api_is_coach();
  1763. $session_visibility = api_get_session_visibility($my_session_id);
  1764. $is_courseAdmin = api_is_course_admin() || api_is_platform_admin();
  1765. if (!$is_courseAdmin && $tutor == true) { // If we also want to check if the user is a tutor...
  1766. $is_courseAdmin = $is_courseAdmin || api_is_course_tutor();
  1767. }
  1768. if (!$is_courseAdmin && $coach == true) { // If we also want to check if the user is a coach...';
  1769. // Check if session visibility is read only for coachs
  1770. if ($session_visibility==SESSION_VISIBLE_READ_ONLY) {
  1771. $is_allowed_coach_to_edit = false;
  1772. }
  1773. if (api_get_setting('allow_coach_to_edit_course_session') == 'true') { // Check if coach is allowed to edit a course
  1774. $is_courseAdmin = $is_courseAdmin || $is_allowed_coach_to_edit;
  1775. } else {
  1776. $is_courseAdmin = $is_courseAdmin;
  1777. }
  1778. }
  1779. if (!$is_courseAdmin && $session_coach == true) {
  1780. $is_courseAdmin = $is_courseAdmin || api_is_coach();
  1781. }
  1782. if (api_get_setting('student_view_enabled') == 'true') { // Check if the student_view is enabled, and if so, if it is activated
  1783. if (!empty($my_session_id)) {
  1784. // Check if session visibility is read only for coachs
  1785. if ($session_visibility == SESSION_VISIBLE_READ_ONLY) {
  1786. $is_allowed_coach_to_edit = false;
  1787. }
  1788. if (api_get_setting('allow_coach_to_edit_course_session') == 'true') { // Check if coach is allowed to edit a course
  1789. $is_allowed = $is_allowed_coach_to_edit;
  1790. } else {
  1791. $is_allowed = false;
  1792. }
  1793. $is_allowed = $is_allowed && $_SESSION['studentview'] != 'studentview';
  1794. } else {
  1795. $is_allowed = $is_courseAdmin && $_SESSION['studentview'] != 'studentview';
  1796. }
  1797. return $is_allowed;
  1798. } else {
  1799. return $is_courseAdmin;
  1800. }
  1801. }
  1802. /**
  1803. * Checks if a student can edit contents in a session depending
  1804. * on the session visibility
  1805. * @param bool Whether to check if the user has the tutor role
  1806. * @param bool Whether to check if the user has the coach role
  1807. * @return boolean, true: the user has the rights to edit, false: he does not
  1808. */
  1809. function api_is_allowed_to_session_edit($tutor = false, $coach = false) {
  1810. if (api_is_allowed_to_edit($tutor, $coach)) {
  1811. // if I'm a teacher, I will return true in order to not affect the normal behaviour of Chamilo tools
  1812. return true;
  1813. } else {
  1814. if (api_get_session_id() == 0) {
  1815. // I'm not in a session so i will return true to not affect the normal behaviour of Chamilo tools
  1816. return true;
  1817. } else {
  1818. // I'm in a session and I'm a student
  1819. $session_id = api_get_session_id();
  1820. // Get the session visibility
  1821. $session_visibility = api_get_session_visibility($session_id); //if 0 the session is still available
  1822. if ($session_visibility != 0) {
  1823. //@todo we could load the session_rel_course_rel_user permission to increase the level of detail
  1824. //echo api_get_user_id();
  1825. //echo api_get_course_id();
  1826. switch ($session_visibility) {
  1827. case SESSION_VISIBLE_READ_ONLY: //1
  1828. return false;
  1829. case SESSION_VISIBLE: //2
  1830. return true;
  1831. case SESSION_INVISIBLE: //3
  1832. return false;
  1833. }
  1834. } else {
  1835. return true;
  1836. }
  1837. }
  1838. }
  1839. }
  1840. /**
  1841. * Checks whether the user is allowed in a specific tool for a specific action
  1842. * @param $tool the tool we are checking if the user has a certain permission
  1843. * @param $action the action we are checking (add, edit, delete, move, visibility)
  1844. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  1845. * @version 1.0
  1846. */
  1847. function api_is_allowed($tool, $action, $task_id = 0) {
  1848. global $_course;
  1849. global $_user;
  1850. if (api_is_course_admin()) {
  1851. return true;
  1852. }
  1853. //if (!$_SESSION['total_permissions'][$_course['code']] and $_course)
  1854. if (is_array($_course) and count($_course) > 0) {
  1855. require_once api_get_path(SYS_CODE_PATH).'permissions/permissions_functions.inc.php';
  1856. require_once api_get_path(LIBRARY_PATH).'groupmanager.lib.php';
  1857. // Getting the permissions of this user
  1858. if ($task_id == 0) {
  1859. $user_permissions = get_permissions('user', $_user['user_id']);
  1860. $_SESSION['total_permissions'][$_course['code']] = $user_permissions;
  1861. }
  1862. // Getting the permissions of the task
  1863. if ($task_id != 0) {
  1864. $task_permissions = get_permissions('task', $task_id);
  1865. /* !!! */$_SESSION['total_permissions'][$_course['code']] = $task_permissions;
  1866. }
  1867. //print_r($_SESSION['total_permissions']);
  1868. // Getting the permissions of the groups of the user
  1869. //$groups_of_user = GroupManager::get_group_ids($_course['db_name'], $_user['user_id']);
  1870. //foreach($groups_of_user as $group)
  1871. //$this_group_permissions = get_permissions('group', $group);
  1872. // Getting the permissions of the courseroles of the user
  1873. $user_courserole_permissions = get_roles_permissions('user', $_user['user_id']);
  1874. // Getting the permissions of the platformroles of the user
  1875. //$user_platformrole_permissions = get_roles_permissions('user', $_user['user_id'], ', platform');
  1876. // Getting the permissions of the roles of the groups of the user
  1877. //foreach($groups_of_user as $group)
  1878. //$this_group_courserole_permissions = get_roles_permissions('group', $group);
  1879. // Getting the permissions of the platformroles of the groups of the user
  1880. //foreach($groups_of_user as $group)
  1881. //$this_group_platformrole_permissions = get_roles_permissions('group', $group, 'platform');
  1882. }
  1883. // If the permissions are limited, we have to map the extended ones to the limited ones
  1884. if (api_get_setting('permissions') == 'limited') {
  1885. if ($action == 'Visibility') {
  1886. $action = 'Edit';
  1887. }
  1888. if ($action == 'Move') {
  1889. $action = 'Edit';
  1890. }
  1891. }
  1892. // The session that contains all the permissions already exists for this course
  1893. // so there is no need to requery everything.
  1894. //my_print_r($_SESSION['total_permissions'][$_course['code']][$tool]);
  1895. if (is_array($_SESSION['total_permissions'][$_course['code']][$tool])) {
  1896. if (in_array($action, $_SESSION['total_permissions'][$_course['code']][$tool])) {
  1897. return true;
  1898. } else {
  1899. return false;
  1900. }
  1901. }
  1902. }
  1903. /**
  1904. * Tells whether this user is an anonymous user
  1905. * @param int User ID (optional, will take session ID if not provided)
  1906. * @param bool Whether to check in the database (true) or simply in the session (false) to see if the current user is the anonymous user
  1907. * @return bool true if this user is anonymous, false otherwise
  1908. */
  1909. function api_is_anonymous($user_id = null, $db_check = false) {
  1910. if (!isset($user_id)) {
  1911. $user_id = api_get_user_id();
  1912. }
  1913. if ($db_check) {
  1914. $info = api_get_user_info($user_id);
  1915. if ($info['status'] == 6) {
  1916. return true;
  1917. }
  1918. }
  1919. global $_user;
  1920. if (!isset($_user)) {
  1921. // In some cases, api_set_anonymous doesn't seem to be triggered in local.inc.php. Make sure it is.
  1922. // Occurs in agenda for admin links - YW
  1923. global $use_anonymous;
  1924. if (isset($use_anonymous) && $use_anonymous) {
  1925. api_set_anonymous();
  1926. }
  1927. return true;
  1928. }
  1929. return isset($_user['is_anonymous']) && $_user['is_anonymous'] === true;
  1930. }
  1931. /**
  1932. * Displays message "You are not allowed here..." and exits the entire script.
  1933. * @param bool Whether or not to print headers (default = false -> does not print them)
  1934. *
  1935. * @author Roan Embrechts
  1936. * @author Yannick Warnier
  1937. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  1938. *
  1939. * @version 1.0, February 2004
  1940. * @version dokeos 1.8, August 2006
  1941. */
  1942. function api_not_allowed($print_headers = false) {
  1943. $home_url = api_get_path(WEB_PATH);
  1944. $user = api_get_user_id();
  1945. $course = api_get_course_id();
  1946. global $this_section;
  1947. $origin = isset($_GET['origin']) ? $_GET['origin'] : '';
  1948. if ($origin == 'learnpath') {
  1949. echo '
  1950. <style type="text/css" media="screen, projection">
  1951. /*<![CDATA[*/
  1952. @import "'.api_get_path(WEB_CODE_PATH).'css/'.api_get_setting('stylesheets').'/default.css";
  1953. /*]]>*/
  1954. </style>';
  1955. }
  1956. if ((isset($user) && !api_is_anonymous()) && (!isset($course) || $course == -1) && empty($_GET['cidReq'])) {
  1957. //if the access is not authorized and there is some login information
  1958. // but the cidReq is not found, assume we are missing course data and send the user
  1959. // to the user_portal
  1960. if ((!headers_sent() or $print_headers) && $origin != 'learnpath') { Display::display_header(''); }
  1961. echo '<div align="center">';
  1962. Display::display_error_message(get_lang('NotAllowedClickBack').'<br /><br /><a href="'.$_SERVER['HTTP_REFERER'].'">'.get_lang('BackToPreviousPage').'</a><br />', false);
  1963. echo '</div>';
  1964. if ($print_headers && $origin != 'learnpath') { Display::display_footer(); }
  1965. die();
  1966. }
  1967. if (!empty($_SERVER['REQUEST_URI']) && (!empty($_GET['cidReq']) || $this_section == SECTION_MYPROFILE)) {
  1968. //only display form and return to the previous URL if there was a course ID included
  1969. if (!empty($user) && !api_is_anonymous()) {
  1970. if ((!headers_sent() || $print_headers) && $origin != 'learnpath') { Display::display_header(''); }
  1971. echo '<div align="center">';
  1972. Display::display_error_message(get_lang('NotAllowedClickBack').'<br /><br /><a href="'.$_SERVER['HTTP_REFERER'].'">'.get_lang('BackToPreviousPage').'</a><br />', false);
  1973. echo '</div>';
  1974. if ($print_headers && $origin != 'learnpath') { Display::display_footer(); }
  1975. die();
  1976. }
  1977. require_once api_get_path(LIBRARY_PATH).'formvalidator/FormValidator.class.php';
  1978. $form = new FormValidator('formLogin', 'post', api_get_self().'?'.Security::remove_XSS($_SERVER['QUERY_STRING']));
  1979. $form->addElement('text', 'login', get_lang('UserName'), array('size' => 17));
  1980. $form->addElement('password', 'password', get_lang('Password'), array('size' => 17));
  1981. $form->addElement('style_submit_button', 'submitAuth', get_lang('LoginEnter'),'class="login"');
  1982. if ((!headers_sent() || $print_headers) && $origin != 'learnpath') { Display::display_header(''); }
  1983. Display::display_error_message(get_lang('NotAllowed').'<br />'.get_lang('PleaseLoginAgainFromFormBelow').'<br />', false);
  1984. echo '<div class="menu" id="menu" style="float:left">';
  1985. echo '<br />';
  1986. $renderer =& $form->defaultRenderer();
  1987. $renderer->setElementTemplate('<div><label>{label}</label></div><div>{element}</div>');
  1988. $form->display();
  1989. /*
  1990. if (api_get_setting('allow_lostpassword') == 'true' || api_get_setting('allow_registration') == 'true') {
  1991. echo '<div class="menusection"><span class="menusectioncaption">'.get_lang('MenuUser').'</span><ul class="menulist">';
  1992. if (api_get_setting('allow_registration') <> 'false') {
  1993. echo '<li><a href="'.api_get_path(WEB_CODE_PATH).'auth/inscription.php">'.get_lang('Reg').'</a></li>';
  1994. }
  1995. if (api_get_setting('allow_lostpassword') == 'true') {
  1996. echo '<li><a href="'.api_get_path(WEB_CODE_PATH).'auth/lostPassword.php">'.get_lang('LostPassword').'</a></li>';
  1997. }
  1998. echo '</ul></div>';
  1999. }*/
  2000. echo '</div>';
  2001. $_SESSION['request_uri'] = $_SERVER['REQUEST_URI'];
  2002. if ($print_headers && $origin != 'learnpath') { Display::display_footer(); }
  2003. die();
  2004. }
  2005. if (!empty($user) && !api_is_anonymous()) {
  2006. if ((!headers_sent() or $print_headers) && $origin != 'learnpath') { Display::display_header(''); }
  2007. echo '<div align="center">';
  2008. Display::display_error_message(get_lang('NotAllowedClickBack').'<br /><br /><a href="'.$_SERVER['HTTP_REFERER'].'">'.get_lang('BackToPreviousPage').'</a><br />', false);
  2009. echo '</div>';
  2010. if ($print_headers && $origin != 'learnpath') {Display::display_footer();}
  2011. die();
  2012. }
  2013. //if no course ID was included in the requested URL, redirect to homepage
  2014. if ($print_headers && $origin != 'learnpath') { Display::display_header(''); }
  2015. echo '<div align="center">';
  2016. Display::display_error_message(get_lang('NotAllowed').'<br /><br /><a href="'.$home_url.'">'.get_lang('PleaseLoginAgainFromHomepage').'</a><br />', false);
  2017. echo '</div>';
  2018. if ($print_headers && $origin != 'learnpath') { Display::display_footer(); }
  2019. die();
  2020. }
  2021. /* WHAT'S NEW
  2022. functions for the what's new icons
  2023. in the user course list */
  2024. /**
  2025. * Gets a UNIX timestamp from a MySQL datetime format string
  2026. * @param $last_post_datetime standard output date in a sql query
  2027. * @return unix timestamp
  2028. * @author Toon Van Hoecke <Toon.VanHoecke@UGent.be>
  2029. * @version October 2003
  2030. * @desc convert sql date to unix timestamp
  2031. */
  2032. function convert_mysql_date($last_post_datetime) {
  2033. list ($last_post_date, $last_post_time) = split(' ', $last_post_datetime);
  2034. list ($year, $month, $day) = explode('-', $last_post_date);
  2035. list ($hour, $min, $sec) = explode(':', $last_post_time);
  2036. return mktime((int)$hour, (int)$min, (int)$sec, (int)$month, (int)$day, (int)$year);
  2037. }
  2038. /**
  2039. * Gets a MySQL datetime format string from a UNIX timestamp
  2040. * @param int UNIX timestamp, as generated by the time() function. Will be generated if parameter not provided
  2041. * @return string MySQL datetime format, like '2009-01-30 12:23:34'
  2042. */
  2043. function api_get_datetime($time = null) {
  2044. if (!isset($time)) { $time = time(); }
  2045. return date('Y-m-d H:i:s', $time);
  2046. }
  2047. /**
  2048. * Gets item visibility from the item_property table
  2049. * @param array Course properties array (result of api_get_course_info())
  2050. * @param string Tool (learnpath, document, etc)
  2051. * @param int The item ID in the given tool
  2052. * @return int -1 on error, 0 if invisible, 1 if visible
  2053. */
  2054. function api_get_item_visibility($_course, $tool, $id) {
  2055. if (!is_array($_course) || count($_course) == 0 || empty($tool) || empty($id)) { return -1; }
  2056. $tool = Database::escape_string($tool);
  2057. $id = Database::escape_string($id);
  2058. $TABLE_ITEMPROPERTY = Database::get_course_table(TABLE_ITEM_PROPERTY, $_course['dbName']);
  2059. $sql = "SELECT visibility FROM $TABLE_ITEMPROPERTY WHERE tool = '$tool' AND ref = $id";
  2060. $res = Database::query($sql);
  2061. if ($res === false || Database::num_rows($res) == 0) { return -1; }
  2062. $row = Database::fetch_array($res);
  2063. return $row['visibility'];
  2064. }
  2065. /**
  2066. * Updates or adds item properties to the Item_propetry table
  2067. * Tool and lastedit_type are language independant strings (langvars->get_lang!)
  2068. *
  2069. * @param $_course : array with course properties
  2070. * @param $tool : tool id, linked to 'rubrique' of the course tool_list (Warning: language sensitive !!)
  2071. * @param $item_id : id of the item itself, linked to key of every tool ('id', ...), "*" = all items of the tool
  2072. * @param $lastedit_type : add or update action (1) message to be translated (in trad4all) : e.g. DocumentAdded, DocumentUpdated;
  2073. * (2) "delete"; (3) "visible"; (4) "invisible";
  2074. * @param $user_id : id of the editing/adding user
  2075. * @param $to_group_id : id of the intended group ( 0 = for everybody), only relevant for $type (1)
  2076. * @param $to_user_id : id of the intended user (always has priority over $to_group_id !), only relevant for $type (1)
  2077. * @param string $start_visible 0000-00-00 00:00:00 format
  2078. * @param unknown_type $end_visible 0000-00-00 00:00:00 format
  2079. * @return boolean False if update fails.
  2080. * @author Toon Van Hoecke <Toon.VanHoecke@UGent.be>, Ghent University
  2081. * @version January 2005
  2082. * @desc update the item_properties table (if entry not exists, insert) of the course
  2083. */
  2084. function api_item_property_update($_course, $tool, $item_id, $lastedit_type, $user_id, $to_group_id = 0, $to_user_id = null, $start_visible = 0, $end_visible = 0, $session_id = 0) {
  2085. // Definition of variables
  2086. $tool = Database::escape_string($tool);
  2087. $item_id = Database::escape_string($item_id);
  2088. $lastedit_type = Database::escape_string($lastedit_type);
  2089. $user_id = Database::escape_string($user_id);
  2090. $to_group_id = Database::escape_string($to_group_id);
  2091. $to_user_id = Database::escape_string($to_user_id);
  2092. $start_visible = Database::escape_string($start_visible);
  2093. $end_visible = Database::escape_string($end_visible);
  2094. $start_visible = ($start_visible == 0) ? '0000-00-00 00:00:00' : $start_visible;
  2095. $end_visible = ($end_visible == 0) ? '0000-00-00 00:00:00' : $end_visible;
  2096. $to_filter = '';
  2097. $time = time();
  2098. $time = date('Y-m-d H:i:s', $time);
  2099. if (!empty($session_id)) {
  2100. $session_id = intval($session_id);
  2101. } else {
  2102. $session_id = api_get_session_id();
  2103. }
  2104. // Definition of tables
  2105. $TABLE_ITEMPROPERTY = Database::get_course_table(TABLE_ITEM_PROPERTY, $_course['dbName']);
  2106. if ($to_user_id <= 0) {
  2107. $to_user_id = null; // No to_user_id set
  2108. }
  2109. if (!is_null($to_user_id)) {
  2110. // $to_user_id has more priority than $to_group_id
  2111. $to_field = 'to_user_id';
  2112. $to_value = $to_user_id;
  2113. } else {
  2114. // $to_user_id is not set
  2115. $to_field = 'to_group_id';
  2116. $to_value = $to_group_id;
  2117. }
  2118. // Set filters for $to_user_id and $to_group_id, with priority for $to_user_id
  2119. $condition_session = '';
  2120. if (!empty($session_id)) {
  2121. $condition_session = " AND id_session = '$session_id' ";
  2122. }
  2123. $filter = "tool='$tool' AND ref='$item_id' $condition_session ";
  2124. if ($item_id == '*') {
  2125. $filter = "tool='$tool' AND visibility<>'2' $condition_session"; // For all (not deleted) items of the tool
  2126. }
  2127. // Check whether $to_user_id and $to_group_id are passed in the function call
  2128. // If both are not passed (both are null) then it is a message for everybody and $to_group_id should be 0 !
  2129. if (is_null($to_user_id) && is_null($to_group_id)) {
  2130. $to_group_id = 0;
  2131. }
  2132. if (!is_null($to_user_id)) {
  2133. $to_filter = " AND to_user_id='$to_user_id' $condition_session"; // Set filter to intended user
  2134. } else {
  2135. if (($to_group_id != 0) && $to_group_id == strval(intval($to_group_id))) {
  2136. $to_filter = " AND to_group_id='$to_group_id' $condition_session"; // Set filter to intended group
  2137. }
  2138. }
  2139. // Update if possible
  2140. $set_type = '';
  2141. switch ($lastedit_type) {
  2142. case 'delete' : // delete = make item only visible for the platform admin
  2143. $visibility = '2';
  2144. if (!empty($session_id)) {
  2145. // Check whether session id already exist into itemp_properties for updating visibility or add it
  2146. $sql = "select id_session FROM $TABLE_ITEMPROPERTY WHERE tool = '$tool' AND ref='$item_id' AND id_session = '$session_id'";
  2147. $rs = Database::query($sql);
  2148. if (Database::num_rows($rs) > 0) {
  2149. $sql = "UPDATE $TABLE_ITEMPROPERTY
  2150. SET lastedit_type='".str_replace('_', '', ucwords($tool))."Deleted', lastedit_date='$time', lastedit_user_id='$user_id', visibility='$visibility', id_session = '$session_id' $set_type
  2151. WHERE $filter";
  2152. } else {
  2153. $sql = "INSERT INTO $TABLE_ITEMPROPERTY
  2154. (tool, ref, insert_date, insert_user_id, lastedit_date, lastedit_type, lastedit_user_id,$to_field, visibility, start_visible, end_visible, id_session)
  2155. VALUES ('$tool','$item_id','$time', '$user_id', '$time', '$lastedit_type','$user_id', '$to_value', '$visibility', '$start_visible','$end_visible', '$session_id')";
  2156. }
  2157. } else {
  2158. $sql = "UPDATE $TABLE_ITEMPROPERTY
  2159. SET lastedit_type='".str_replace('_', '', ucwords($tool))."Deleted', lastedit_date='$time', lastedit_user_id='$user_id', visibility='$visibility' $set_type
  2160. WHERE $filter";
  2161. }
  2162. break;
  2163. case 'visible' : // Change item to visible
  2164. $visibility = '1';
  2165. if (!empty($session_id)) {
  2166. // Check whether session id already exist into itemp_properties for updating visibility or add it
  2167. $sql = "SELECT id_session FROM $TABLE_ITEMPROPERTY WHERE tool = '$tool' AND ref='$item_id' AND id_session = '$session_id'";
  2168. $rs = Database::query($sql);
  2169. if (Database::num_rows($rs) > 0) {
  2170. $sql = "UPDATE $TABLE_ITEMPROPERTY
  2171. SET lastedit_type='".str_replace('_', '', ucwords($tool))."Visible', lastedit_date='$time', lastedit_user_id='$user_id', visibility='$visibility', id_session = '$session_id' $set_type
  2172. WHERE $filter";
  2173. } else {
  2174. $sql = "INSERT INTO $TABLE_ITEMPROPERTY
  2175. (tool, ref, insert_date, insert_user_id, lastedit_date, lastedit_type, lastedit_user_id,$to_field, visibility, start_visible, end_visible, id_session)
  2176. VALUES ('$tool','$item_id','$time', '$user_id', '$time', '$lastedit_type','$user_id', '$to_value', '$visibility', '$start_visible','$end_visible', '$session_id')";
  2177. }
  2178. } else {
  2179. $sql = "UPDATE $TABLE_ITEMPROPERTY
  2180. SET lastedit_type='".str_replace('_', '', ucwords($tool))."Visible', lastedit_date='$time', lastedit_user_id='$user_id', visibility='$visibility' $set_type
  2181. WHERE $filter";
  2182. }
  2183. break;
  2184. case 'invisible' : // Change item to invisible
  2185. $visibility = '0';
  2186. if (!empty($session_id)) {
  2187. // Check whether session id already exist into itemp_properties for updating visibility or add it
  2188. $sql = "SELECT id_session FROM $TABLE_ITEMPROPERTY WHERE tool = '$tool' AND ref='$item_id' AND id_session = '$session_id'";
  2189. $rs = Database::query($sql);
  2190. if (Database::num_rows($rs) > 0) {
  2191. $sql = "UPDATE $TABLE_ITEMPROPERTY
  2192. SET lastedit_type='".str_replace('_', '', ucwords($tool))."Invisible', lastedit_date='$time', lastedit_user_id='$user_id', visibility='$visibility', id_session = '$session_id' $set_type
  2193. WHERE $filter";
  2194. } else {
  2195. $sql = "INSERT INTO $TABLE_ITEMPROPERTY
  2196. (tool, ref, insert_date, insert_user_id, lastedit_date, lastedit_type, lastedit_user_id,$to_field, visibility, start_visible, end_visible, id_session)
  2197. VALUES ('$tool','$item_id','$time', '$user_id', '$time', '$lastedit_type','$user_id', '$to_value', '$visibility', '$start_visible','$end_visible', '$session_id')";
  2198. }
  2199. } else {
  2200. $sql = "UPDATE $TABLE_ITEMPROPERTY
  2201. SET lastedit_type='".str_replace('_', '', ucwords($tool))."Invisible', lastedit_date='$time', lastedit_user_id='$user_id', visibility='$visibility' $set_type
  2202. WHERE $filter";
  2203. }
  2204. break;
  2205. default : // The item will be added or updated
  2206. $set_type = ", lastedit_type='$lastedit_type' ";
  2207. $visibility = '1';
  2208. $filter .= $to_filter;
  2209. $sql = "UPDATE $TABLE_ITEMPROPERTY
  2210. SET lastedit_date='$time', lastedit_user_id='$user_id' $set_type
  2211. WHERE $filter";
  2212. }
  2213. $res = Database::query($sql);
  2214. // Insert if no entries are found (can only happen in case of $lastedit_type switch is 'default')
  2215. if (Database::affected_rows() == 0) {
  2216. $sql = "INSERT INTO $TABLE_ITEMPROPERTY
  2217. (tool,ref,insert_date,insert_user_id,lastedit_date,lastedit_type, lastedit_user_id,$to_field, visibility, start_visible, end_visible, id_session)
  2218. VALUES ('$tool','$item_id','$time', '$user_id', '$time', '$lastedit_type','$user_id', '$to_value','$visibility','$start_visible','$end_visible', '$session_id')";
  2219. $res = Database::query($sql);
  2220. if (!$res) {
  2221. return false;
  2222. }
  2223. }
  2224. return true;
  2225. }
  2226. /**
  2227. * Gets item property id from tool of a course
  2228. * @param string course code
  2229. * @param string tool name, linked to 'rubrique' of the course tool_list (Warning: language sensitive !!)
  2230. * @param int id of the item itself, linked to key of every tool ('id', ...), "*" = all items of the tool
  2231. */
  2232. function api_get_item_property_id ($course_code, $tool, $ref) {
  2233. $course_info = api_get_course_info($course_code);
  2234. $tool = Database::escape_string($tool);
  2235. $ref = intval($ref);
  2236. // Definition of tables
  2237. $TABLE_ITEMPROPERTY = Database::get_course_table(TABLE_ITEM_PROPERTY,$course_info['dbName']);
  2238. $sql = "SELECT id FROM $TABLE_ITEMPROPERTY WHERE tool = '$tool' AND ref = '$ref' ";
  2239. $rs = Database::query($sql);
  2240. $item_property_id = '';
  2241. if (Database::num_rows($rs) > 0) {
  2242. $row = Database::fetch_array($rs);
  2243. $item_property_id = $row['id'];
  2244. }
  2245. return $item_property_id;
  2246. }
  2247. /* Language Dropdown */
  2248. /**
  2249. * Displays a combobox so the user can select his/her preferred language.
  2250. * @param string The desired name= value for the select
  2251. * @return string
  2252. */
  2253. function api_get_languages_combo($name = 'language') {
  2254. $ret = '';
  2255. $platformLanguage = api_get_setting('platformLanguage');
  2256. // Retrieve a complete list of all the languages.
  2257. $language_list = api_get_languages();
  2258. if (count($language_list['name']) < 2) {
  2259. return $ret;
  2260. }
  2261. // The the current language of the user so that his/her language occurs as selected in the dropdown menu
  2262. if (isset($_SESSION['user_language_choice'])) {
  2263. $default = $_SESSION['user_language_choice'];
  2264. } else {
  2265. $default = $platformLanguage;
  2266. }
  2267. $languages = $language_list['name'];
  2268. $folder = $language_list['folder'];
  2269. $ret .= '<select name="'.$name.'">';
  2270. foreach ($languages as $key => $value) {
  2271. if ($folder[$key] == $default) {
  2272. $selected = ' selected="selected"';
  2273. } else {
  2274. $selected = '';
  2275. }
  2276. $ret .= sprintf('<option value=%s" %s>%s</option>'."\n", $folder[$key], $selected, $value);
  2277. }
  2278. $ret .= '</select>';
  2279. return $ret;
  2280. }
  2281. /**
  2282. * Displays a form (drop down menu) so the user can select his/her preferred language.
  2283. * The form works with or without javascript
  2284. * @param boolean Hide form if only one language available (defaults to false = show the box anyway)
  2285. * @return void Display the box directly
  2286. */
  2287. function api_display_language_form($hide_if_no_choice = false) {
  2288. // Retrieve a complete list of all the languages.
  2289. $language_list = api_get_languages();
  2290. if (count($language_list['name']) <= 1 && $hide_if_no_choice) {
  2291. return; //don't show any form
  2292. }
  2293. // The the current language of the user so that his/her language occurs as selected in the dropdown menu
  2294. if (isset($_SESSION['user_language_choice'])) {
  2295. $user_selected_language = $_SESSION['user_language_choice'];
  2296. }
  2297. if (empty($user_selected_language)) {
  2298. $user_selected_language = api_get_setting('platformLanguage');
  2299. }
  2300. $original_languages = $language_list['name'];
  2301. $folder = $language_list['folder']; // this line is probably no longer needed
  2302. ?>
  2303. <script type="text/javascript">
  2304. <!--
  2305. function jumpMenu(targ,selObj,restore){ //v3.0
  2306. eval(targ+".location='"+selObj.options[selObj.selectedIndex].value+"'");
  2307. if (restore) selObj.selectedIndex=0;
  2308. }
  2309. //-->
  2310. </script>
  2311. <?php
  2312. echo '<form id="lang_form" name="lang_form" method="post" action="'.api_get_self().'">', "<select name=\"language_list\" onchange=\"javascript: jumpMenu('parent',this,0);\">";
  2313. foreach ($original_languages as $key => $value) {
  2314. if ($folder[$key] == $user_selected_language) {
  2315. $option_end = ' selected="selected" >';
  2316. } else {
  2317. $option_end = '>';
  2318. }
  2319. echo '<option value="'.api_get_self().'?language='.$folder[$key].'"'.$option_end;
  2320. //echo substr($value,0,16); //cut string to keep 800x600 aspect
  2321. echo $value, '</option>', "\n";
  2322. }
  2323. echo '</select>';
  2324. echo '<noscript><input type="submit" name="user_select_language" value="'.get_lang('Ok').'" /></noscript>';
  2325. echo '</form>';
  2326. }
  2327. /**
  2328. * Returns a list of all the languages that are made available by the admin.
  2329. * @return array An array with all languages. Structure of the array is
  2330. * array['name'] = An array with the name of every language
  2331. * array['folder'] = An array with the corresponding names of the language-folders in the filesystem
  2332. */
  2333. function api_get_languages() {
  2334. $tbl_language = Database::get_main_table(TABLE_MAIN_LANGUAGE);
  2335. $sql = "SELECT * FROM $tbl_language WHERE available='1' ORDER BY original_name ASC";
  2336. $result = Database::query($sql);
  2337. while ($row = Database::fetch_array($result)) {
  2338. $language_list['name'][] = $row['original_name'];
  2339. $language_list['folder'][] = $row['dokeos_folder'];
  2340. }
  2341. return $language_list;
  2342. }
  2343. /**
  2344. * Returns the id (the database id) of a language
  2345. * @param string language name (the corresponding name of the language-folder in the filesystem)
  2346. * @return int id of the language
  2347. */
  2348. function api_get_language_id($language) {
  2349. $tbl_language = Database::get_main_table(TABLE_MAIN_LANGUAGE);
  2350. $language = Database::escape_string($language);
  2351. $sql = "SELECT id FROM $tbl_language WHERE available='1' AND dokeos_folder = '$language' ORDER BY dokeos_folder ASC";
  2352. $result = Database::query($sql);
  2353. $row = Database::fetch_array($result);
  2354. return $row['id'];
  2355. }
  2356. /**
  2357. * Returns a list of CSS themes currently available in the CSS folder
  2358. * @return array List of themes directories from the css folder
  2359. * Note: Directory names (names of themes) in the file system should contain ASCII-characters only.
  2360. */
  2361. function api_get_themes() {
  2362. $cssdir = api_get_path(SYS_PATH).'main/css/';
  2363. $list_dir = array();
  2364. $list_name = array();
  2365. if (@is_dir($cssdir)) {
  2366. $themes = @scandir($cssdir);
  2367. if (is_array($themes)) {
  2368. if ($themes !== false) {
  2369. sort($themes);
  2370. foreach ($themes as & $theme) {
  2371. if (substr($theme, 0, 1) == '.') {
  2372. continue;
  2373. } else {
  2374. if (@is_dir($cssdir.$theme)) {
  2375. $list_dir[] = $theme;
  2376. $list_name[] = ucwords(str_replace('_', ' ', $theme));
  2377. }
  2378. }
  2379. }
  2380. }
  2381. }
  2382. }
  2383. return array($list_dir, $list_name);
  2384. }
  2385. /* WYSIWYG EDITOR
  2386. functions for the WYSIWYG html editor, TeX parsing...
  2387. Please, try to avoid using the following two functions. The preferable way to put
  2388. an editor's instance on a page is through using a FormValidator's class method. */
  2389. /**
  2390. * Displays the WYSIWYG editor for online editing of html
  2391. * @param string $name The name of the form-element
  2392. * @param string $content The default content of the html-editor
  2393. * @param int $height The height of the form element
  2394. * @param int $width The width of the form element
  2395. * @param string $attributes (optional) attributes for the form element
  2396. * @param array $editor_config (optional) Configuration options for the html-editor
  2397. */
  2398. function api_disp_html_area($name, $content = '', $height = '', $width = '100%', $attributes = null, $editor_config = null) {
  2399. global $_configuration, $_course, $fck_attribute;
  2400. require_once api_get_path(LIBRARY_PATH).'formvalidator/Element/html_editor.php';
  2401. $editor = new HTML_QuickForm_html_editor($name, null, $attributes, $editor_config);
  2402. $editor->setValue($content);
  2403. // The global variable $fck_attribute has been deprecated. It stays here for supporting old external code.
  2404. if( $height != '') {
  2405. $fck_attribute['Height'] = $height;
  2406. }
  2407. if( $width != '') {
  2408. $fck_attribute['Width'] = $width;
  2409. }
  2410. echo $editor->toHtml();
  2411. }
  2412. /**
  2413. * Returns generated html for showing the WYSIWYG editor on the page
  2414. * @param string $name The name of the form-element
  2415. * @param string $content The default content of the html-editor
  2416. * @param int $height The height of the form element
  2417. * @param int $width The width of the form element
  2418. * @param string $attributes (optional) attributes for the form element
  2419. * @param array $editor_config (optional) Configuration options for the html-editor
  2420. */
  2421. function api_return_html_area($name, $content = '', $height = '', $width = '100%', $attributes = null, $editor_config = null) {
  2422. global $_configuration, $_course, $fck_attribute;
  2423. require_once api_get_path(LIBRARY_PATH).'formvalidator/Element/html_editor.php';
  2424. $editor = new HTML_QuickForm_html_editor($name, null, $attributes, $editor_config);
  2425. $editor->setValue($content);
  2426. // The global variable $fck_attribute has been deprecated. It stays here for supporting old external code.
  2427. if ($height != '') {
  2428. $fck_attribute['Height'] = $height;
  2429. }
  2430. if ($width != '') {
  2431. $fck_attribute['Width'] = $width;
  2432. }
  2433. return $editor->toHtml();
  2434. }
  2435. /**
  2436. * Find the largest sort value in a given user_course_category
  2437. * This function is used when we are moving a course to a different category
  2438. * and also when a user subscribes to courses (the new course is added at the end of the main category
  2439. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  2440. * @param int $user_course_category: the id of the user_course_category
  2441. * @return int the value of the highest sort of the user_course_category
  2442. */
  2443. function api_max_sort_value($user_course_category, $user_id) {
  2444. $tbl_course_user = Database::get_main_table(TABLE_MAIN_COURSE_USER);
  2445. $sql_max = "SELECT max(sort) as max_sort FROM $tbl_course_user WHERE user_id='".$user_id."' AND relation_type<>".COURSE_RELATION_TYPE_RRHH." AND user_course_cat='".$user_course_category."'";
  2446. $result_max = Database::query($sql_max);
  2447. if (Database::num_rows($result_max) == 1) {
  2448. $row_max = Database::fetch_array($result_max);
  2449. return $row_max['max_sort'];
  2450. }
  2451. return 0;
  2452. }
  2453. /**
  2454. * This function converts the string "true" or "false" to a boolean true or false.
  2455. * This function is in the first place written for the Chamilo Config Settings (also named AWACS)
  2456. * @param string "true" or "false"
  2457. * @return boolean true or false
  2458. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  2459. */
  2460. function string_2_boolean($string) {
  2461. if ($string == 'true') {
  2462. return true;
  2463. }
  2464. if ($string == 'false') {
  2465. return false;
  2466. }
  2467. return false;
  2468. }
  2469. /**
  2470. * Determines the number of plugins installed for a given location
  2471. */
  2472. function api_number_of_plugins($location) {
  2473. global $_plugins;
  2474. return isset($_plugins[$location]) && is_array($_plugins[$location]) ? count($_plugins[$location]) : 0;
  2475. }
  2476. /**
  2477. * including the necessary plugins
  2478. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  2479. */
  2480. function api_plugin($location) {
  2481. global $_plugins;
  2482. if (isset($_plugins[$location]) && is_array($_plugins[$location])) {
  2483. foreach ($_plugins[$location] as $this_plugin) {
  2484. require_once api_get_path(SYS_PLUGIN_PATH)."$this_plugin/index.php";
  2485. }
  2486. }
  2487. }
  2488. /**
  2489. * Checks to see wether a certain plugin is installed.
  2490. * @return boolean true if the plugin is installed, false otherwise.
  2491. */
  2492. function api_is_plugin_installed($plugin_list, $plugin_name) {
  2493. if(is_array($plugin_list)) {
  2494. foreach ($plugin_list as $plugin_location) {
  2495. if (array_search($plugin_name, $plugin_location) !== false) { return true; }
  2496. }
  2497. }
  2498. return false;
  2499. }
  2500. /**
  2501. * Transforms a number of seconds in hh:mm:ss format
  2502. * @author Julian Prud'homme
  2503. * @param integer the number of seconds
  2504. * @return string the formated time
  2505. */
  2506. function api_time_to_hms($seconds) {
  2507. // seconds = -1 means that we have wrong data in the db
  2508. if ($seconds == -1) {
  2509. return get_lang('Unknown').Display::return_icon('info2.gif', get_lang('WrongDatasForTimeSpentOnThePlatform'), array('align' => 'absmiddle', 'hspace' => '3px'));
  2510. }
  2511. // How many hours ?
  2512. $hours = floor($seconds / 3600);
  2513. // How many minutes ?
  2514. $min = floor(($seconds - ($hours * 3600)) / 60);
  2515. // How many seconds
  2516. $sec = floor($seconds - ($hours * 3600) - ($min * 60));
  2517. if ($sec < 10) {
  2518. $sec = "0$sec";
  2519. }
  2520. if ($min < 10) {
  2521. $min = "0$min";
  2522. }
  2523. return "$hours:$min:$sec";
  2524. }
  2525. /* FILE SYSTEM RELATED FUNCTIONS */
  2526. /**
  2527. * Returns the permissions to be assigned to every newly created directory by the web-server.
  2528. * The returnd value is based on the platform administrator's setting "Administration > Configuration settings > Security > Permissions for new directories".
  2529. * @return int Returns the permissions in the format "Owner-Group-Others, Read-Write-Execute", as an integer value.
  2530. */
  2531. function api_get_permissions_for_new_directories() {
  2532. static $permissions;
  2533. if (!isset($permissions)) {
  2534. $permissions = trim(api_get_setting('permissions_for_new_directories'));
  2535. // The default value 0777 is according to that in the platform administration panel after fresh system installation.
  2536. $permissions = octdec(!empty($permissions) ? $permissions : '0777');
  2537. }
  2538. return $permissions;
  2539. }
  2540. /**
  2541. * Returns the permissions to be assigned to every newly created directory by the web-server.
  2542. * The returnd value is based on the platform administrator's setting "Administration > Configuration settings > Security > Permissions for new files".
  2543. * @return int Returns the permissions in the format "Owner-Group-Others, Read-Write-Execute", as an integer value.
  2544. */
  2545. function api_get_permissions_for_new_files() {
  2546. static $permissions;
  2547. if (!isset($permissions)) {
  2548. $permissions = trim(api_get_setting('permissions_for_new_files'));
  2549. // The default value 0666 is according to that in the platform administration panel after fresh system installation.
  2550. $permissions = octdec(!empty($permissions) ? $permissions : '0666');
  2551. }
  2552. return $permissions;
  2553. }
  2554. /**
  2555. * sys_get_temp_dir() was introduced as of PHP 5.2.1
  2556. * For older PHP versions the following implementation is to be activated.
  2557. * @link Based on http://www.phpit.net/article/creating-zip-tar-archives-dynamically-php/2/
  2558. */
  2559. if (!function_exists('sys_get_temp_dir')) {
  2560. function sys_get_temp_dir() {
  2561. // Try to get from environment variable
  2562. if (!empty($_ENV['TMP'])) {
  2563. return realpath($_ENV['TMP']);
  2564. }
  2565. if (!empty($_ENV['TMPDIR'])) {
  2566. return realpath($_ENV['TMPDIR']);
  2567. }
  2568. if (!empty($_ENV['TEMP'])) {
  2569. return realpath($_ENV['TEMP']);
  2570. }
  2571. // Detect by creating a temporary file
  2572. // Try to use system's temporary directory
  2573. // as random name shouldn't exist
  2574. $temp_file = tempnam(md5(uniqid(rand(), true)), '');
  2575. if ($temp_file) {
  2576. $temp_dir = realpath(dirname($temp_file));
  2577. @unlink( $temp_file );
  2578. return $temp_dir;
  2579. }
  2580. return false;
  2581. }
  2582. }
  2583. /**
  2584. * Deletes a file, or a folder and its contents
  2585. *
  2586. * @author Aidan Lister <aidan@php.net>
  2587. * @version 1.0.3
  2588. * @param string $dirname Directory to delete
  2589. * @return bool Returns TRUE on success, FALSE on failure
  2590. * @link http://aidanlister.com/2004/04/recursively-deleting-a-folder-in-php/
  2591. * @author Yannick Warnier, adaptation for the Chamilo LMS, April, 2008
  2592. * @author Ivan Tcholakov, a sanity check about Directory class creation has been added, September, 2009
  2593. */
  2594. function rmdirr($dirname) {
  2595. // A sanity check
  2596. if (!file_exists($dirname)) {
  2597. return false;
  2598. }
  2599. // Simple delete for a file
  2600. if (is_file($dirname) || is_link($dirname)) {
  2601. $res = unlink($dirname);
  2602. if ($res === false) {
  2603. error_log(__FILE__.' line '.__LINE__.': '.((bool)ini_get('track_errors') ? $php_errormsg : 'error not recorded because track_errors is off in your php.ini'), 0);
  2604. }
  2605. return $res;
  2606. }
  2607. // Loop through the folder
  2608. $dir = dir($dirname);
  2609. // A sanity check
  2610. $is_object_dir = is_object($dir);
  2611. if ($is_object_dir) {
  2612. while (false !== $entry = $dir->read()) {
  2613. // Skip pointers
  2614. if ($entry == '.' || $entry == '..') {
  2615. continue;
  2616. }
  2617. // Recurse
  2618. rmdirr("$dirname/$entry");
  2619. }
  2620. }
  2621. // Clean up
  2622. if ($is_object_dir) {
  2623. $dir->close();
  2624. }
  2625. $res = rmdir($dirname);
  2626. if ($res === false) {
  2627. error_log(__FILE__.' line '.__LINE__.': '.((bool)ini_get('track_errors') ? $php_errormsg : 'error not recorded because track_errors is off in your php.ini'), 0);
  2628. }
  2629. return $res;
  2630. }
  2631. // TODO: This function is to be simplified. File access modes to be implemented.
  2632. /**
  2633. * function adapted from a php.net comment
  2634. * copy recursively a folder
  2635. * @param the source folder
  2636. * @param the dest folder
  2637. * @param an array of excluded file_name (without extension)
  2638. * @param copied_files the returned array of copied files
  2639. */
  2640. function copyr($source, $dest, $exclude = array(), $copied_files = array()) {
  2641. // Simple copy for a file
  2642. if (is_file($source)) {
  2643. $path_info = pathinfo($source);
  2644. if (!in_array($path_info['filename'], $exclude)) {
  2645. copy($source, $dest);
  2646. }
  2647. return;
  2648. }
  2649. // Make destination directory
  2650. if (!is_dir($dest)) {
  2651. mkdir($dest, api_get_permissions_for_new_directories());
  2652. }
  2653. // Loop through the folder
  2654. $dir = dir($source);
  2655. while (false !== $entry = $dir->read()) {
  2656. // Skip pointers
  2657. if ($entry == '.' || $entry == '..') {
  2658. continue;
  2659. }
  2660. // Deep copy directories
  2661. if ($dest !== "$source/$entry") {
  2662. $files = copyr("$source/$entry", "$dest/$entry", $exclude, $copied_files);
  2663. }
  2664. }
  2665. // Clean up
  2666. $dir->close();
  2667. return $files;
  2668. }
  2669. // TODO: Using DIRECTORY_SEPARATOR is not recommended, this is an obsolete approach. Documentation header to be added here.
  2670. function copy_folder_course_session($pathname, $base_path_document,$session_id,$course_info, $document) {
  2671. $table = Database :: get_course_table(TABLE_DOCUMENT, $course_info['dbName']);
  2672. $session_id = intval($session_id);
  2673. // Check if directory already exists
  2674. if (is_dir($pathname) || empty($pathname)) {
  2675. return true;
  2676. }
  2677. // Ensure a file does not already exist with the same name
  2678. if (is_file($pathname)) {
  2679. trigger_error('copy_folder_course_session(): File exists', E_USER_WARNING);
  2680. return false;
  2681. }
  2682. $folders = explode(DIRECTORY_SEPARATOR,str_replace($base_path_document.DIRECTORY_SEPARATOR,'',$pathname));
  2683. $new_pathname = $base_path_document;
  2684. $path = '';
  2685. foreach ($folders as $folder) {
  2686. $new_pathname .= DIRECTORY_SEPARATOR.$folder;
  2687. $path .= DIRECTORY_SEPARATOR.$folder;
  2688. if (!file_exists($new_pathname)) {
  2689. $sql = "SELECT * FROM $table WHERE path = '$path' AND filetype = 'folder' AND session_id = '$session_id'";
  2690. $rs1 = Database::query($sql);
  2691. $num_rows = Database::num_rows($rs1);
  2692. if ($num_rows == 0) {
  2693. mkdir($new_pathname, api_get_permissions_for_new_directories());
  2694. // Insert new folder with destination session_id
  2695. $sql = "INSERT INTO ".$table." SET path = '$path', comment = '".Database::escape_string($document->comment)."', title = '".Database::escape_string(basename($new_pathname))."' ,filetype='folder', size= '0', session_id = '$session_id'";
  2696. Database::query($sql);
  2697. $document_id = Database::insert_id();
  2698. api_item_property_update($course_info,TOOL_DOCUMENT,$document_id,'FolderCreated',api_get_user_id(),0,0,null,null,$session_id);
  2699. }
  2700. }
  2701. } // en foreach
  2702. }
  2703. // TODO: chmodr() is a better name. Some corrections are needed. Documentation header to be added here.
  2704. function api_chmod_R($path, $filemode) {
  2705. if (!is_dir($path)) {
  2706. return chmod($path, $filemode);
  2707. }
  2708. $handler = opendir($path);
  2709. while ($file = readdir($handler)) {
  2710. if ($file != '.' && $file != '..') {
  2711. $fullpath = "$path/$file";
  2712. if (!is_dir($fullpath)) {
  2713. if (!chmod($fullpath, $filemode)) {
  2714. return false;
  2715. }
  2716. } else {
  2717. if (!api_chmod_R($fullpath, $filemode)) {
  2718. return false;
  2719. }
  2720. }
  2721. }
  2722. }
  2723. closedir($handler);
  2724. return chmod($path, $filemode);
  2725. }
  2726. // TODO: Where the following function has been copy/pased from? There is no information about author and license. Style, coding conventions...
  2727. /**
  2728. * Parse info file format. (e.g: file.info)
  2729. *
  2730. * Files should use an ini-like format to specify values.
  2731. * White-space generally doesn't matter, except inside values.
  2732. * e.g.
  2733. *
  2734. * @verbatim
  2735. * key = value
  2736. * key = "value"
  2737. * key = 'value'
  2738. * key = "multi-line
  2739. *
  2740. * value"
  2741. * key = 'multi-line
  2742. *
  2743. * value'
  2744. * key
  2745. * =
  2746. * 'value'
  2747. * @endverbatim
  2748. *
  2749. * Arrays are created using a GET-like syntax:
  2750. *
  2751. * @verbatim
  2752. * key[] = "numeric array"
  2753. * key[index] = "associative array"
  2754. * key[index][] = "nested numeric array"
  2755. * key[index][index] = "nested associative array"
  2756. * @endverbatim
  2757. *
  2758. * PHP constants are substituted in, but only when used as the entire value:
  2759. *
  2760. * Comments should start with a semi-colon at the beginning of a line.
  2761. *
  2762. * This function is NOT for placing arbitrary module-specific settings. Use
  2763. * variable_get() and variable_set() for that.
  2764. *
  2765. * Information stored in the module.info file:
  2766. * - name: The real name of the module for display purposes.
  2767. * - description: A brief description of the module.
  2768. * - dependencies: An array of shortnames of other modules this module depends on.
  2769. * - package: The name of the package of modules this module belongs to.
  2770. *
  2771. * Example of .info file:
  2772. * @verbatim
  2773. * name = Forum
  2774. * description = Enables threaded discussions about general topics.
  2775. * dependencies[] = taxonomy
  2776. * dependencies[] = comment
  2777. * package = Core - optional
  2778. * version = VERSION
  2779. * @endverbatim
  2780. *
  2781. * @param $filename
  2782. * The file we are parsing. Accepts file with relative or absolute path.
  2783. * @return
  2784. * The info array.
  2785. */
  2786. function parse_info_file($filename) {
  2787. $info = array();
  2788. if (!file_exists($filename)) {
  2789. return $info;
  2790. }
  2791. $data = file_get_contents($filename);
  2792. if (preg_match_all('
  2793. @^\s* # Start at the beginning of a line, ignoring leading whitespace
  2794. ((?:
  2795. [^=;\[\]]| # Key names cannot contain equal signs, semi-colons or square brackets,
  2796. \[[^\[\]]*\] # unless they are balanced and not nested
  2797. )+?)
  2798. \s*=\s* # Key/value pairs are separated by equal signs (ignoring white-space)
  2799. (?:
  2800. ("(?:[^"]|(?<=\\\\)")*")| # Double-quoted string, which may contain slash-escaped quotes/slashes
  2801. (\'(?:[^\']|(?<=\\\\)\')*\')| # Single-quoted string, which may contain slash-escaped quotes/slashes
  2802. ([^\r\n]*?) # Non-quoted string
  2803. )\s*$ # Stop at the next end of a line, ignoring trailing whitespace
  2804. @msx', $data, $matches, PREG_SET_ORDER)) {
  2805. foreach ($matches as $match) {
  2806. // Fetch the key and value string
  2807. $i = 0;
  2808. foreach (array('key', 'value1', 'value2', 'value3') as $var) {
  2809. $$var = isset($match[++$i]) ? $match[$i] : '';
  2810. }
  2811. $value = stripslashes(substr($value1, 1, -1)) . stripslashes(substr($value2, 1, -1)) . $value3;
  2812. // Parse array syntax
  2813. $keys = preg_split('/\]?\[/', rtrim($key, ']'));
  2814. $last = array_pop($keys);
  2815. $parent = &$info;
  2816. // Create nested arrays
  2817. foreach ($keys as $key) {
  2818. if ($key == '') {
  2819. $key = count($parent);
  2820. }
  2821. if (!isset($parent[$key]) || !is_array($parent[$key])) {
  2822. $parent[$key] = array();
  2823. }
  2824. $parent = &$parent[$key];
  2825. }
  2826. // Handle PHP constants
  2827. if (defined($value)) {
  2828. $value = constant($value);
  2829. }
  2830. // Insert actual value
  2831. if ($last == '') {
  2832. $last = count($parent);
  2833. }
  2834. $parent[$last] = $value;
  2835. }
  2836. }
  2837. return $info;
  2838. }
  2839. /**
  2840. * Gets Chamilo version from the configuration files
  2841. * @return string A string of type "1.8.4", or an empty string if the version could not be found
  2842. */
  2843. function api_get_version() {
  2844. global $_configuration;
  2845. return (string)$_configuration['system_version'];
  2846. }
  2847. /**
  2848. * Gets the software name (the name/brand of the Chamilo-based customized system)
  2849. * @return string
  2850. */
  2851. function api_get_software_name() {
  2852. global $_configuration;
  2853. if (isset($_configuration['software_name']) && !empty($_configuration['software_name'])) {
  2854. return $_configuration['software_name'];
  2855. } else {
  2856. return 'Chamilo';
  2857. }
  2858. }
  2859. /**
  2860. * Checks whether status given in parameter exists in the platform
  2861. * @param mixed the status (can be either int either string)
  2862. * @return true if the status exists, else returns false
  2863. */
  2864. function api_status_exists($status_asked) {
  2865. global $_status_list;
  2866. return in_array($status_asked, $_status_list) ? true : isset($_status_list[$status_asked]);
  2867. }
  2868. /**
  2869. * Checks whether status given in parameter exists in the platform
  2870. * @param mixed the status (can be either int either string)
  2871. * @return true if the status exists, else returns false
  2872. */
  2873. function api_status_key($status) {
  2874. global $_status_list;
  2875. return isset($_status_list[$status]) ? $status : array_search($status, $_status_list);
  2876. }
  2877. /**
  2878. * Gets the status langvars list
  2879. * @return array the list of status with their translations
  2880. */
  2881. function api_get_status_langvars() {
  2882. return array(
  2883. COURSEMANAGER => get_lang('Teacher', ''),
  2884. SESSIONADMIN => get_lang('SessionsAdmin', ''),
  2885. DRH => get_lang('Drh', ''),
  2886. STUDENT => get_lang('Student', ''),
  2887. ANONYMOUS => get_lang('Anonymous', '')
  2888. );
  2889. }
  2890. /**
  2891. * Sets a platform configuration setting to a given value
  2892. * @param string The variable we want to update
  2893. * @param string The value we want to record
  2894. * @param string The sub-variable if any (in most cases, this will remain null)
  2895. * @param string The category if any (in most cases, this will remain null)
  2896. * @param int The access_url for which this parameter is valid
  2897. */
  2898. function api_set_setting($var, $value, $subvar = null, $cat = null, $access_url = 1) {
  2899. if (empty($var)) { return false; }
  2900. $t_settings = Database::get_main_table(TABLE_MAIN_SETTINGS_CURRENT);
  2901. $var = Database::escape_string($var);
  2902. $value = Database::escape_string($value);
  2903. $access_url = (int)$access_url;
  2904. if (empty($access_url)) { $access_url = 1; }
  2905. $select = "SELECT id FROM $t_settings WHERE variable = '$var' ";
  2906. if (!empty($subvar)) {
  2907. $subvar = Database::escape_string($subvar);
  2908. $select .= " AND subkey = '$subvar'";
  2909. }
  2910. if (!empty($cat)) {
  2911. $cat = Database::escape_string($cat);
  2912. $select .= " AND category = '$cat'";
  2913. }
  2914. if ($access_url > 1) {
  2915. $select .= " AND access_url = $access_url";
  2916. } else {
  2917. $select .= " AND access_url = 1 ";
  2918. }
  2919. $res = Database::query($select);
  2920. if (Database::num_rows($res) > 0) {
  2921. // Found item for this access_url
  2922. $row = Database::fetch_array($res);
  2923. $update = "UPDATE $t_settings SET selected_value = '$value' WHERE id = ".$row['id'] ;
  2924. $res = Database::query($update);
  2925. } else {
  2926. // Item not found for this access_url, we have to check if it exist with access_url = 1
  2927. $select = "SELECT * FROM $t_settings WHERE variable = '$var' AND access_url = 1 ";
  2928. // Just in case
  2929. if ($access_url == 1) {
  2930. if (!empty($subvar)) {
  2931. $select .= " AND subkey = '$subvar'";
  2932. }
  2933. if (!empty($cat)) {
  2934. $select .= " AND category = '$cat'";
  2935. }
  2936. $res = Database::query($select);
  2937. if (Database::num_rows($res) > 0) { // We have a setting for access_url 1, but none for the current one, so create one
  2938. $row = Database::fetch_array($res);
  2939. $insert = "INSERT INTO $t_settings " .
  2940. "(variable,subkey," .
  2941. "type,category," .
  2942. "selected_value,title," .
  2943. "comment,scope," .
  2944. "subkeytext,access_url)" .
  2945. " VALUES " .
  2946. "('".$row['variable']."',".(!empty($row['subkey']) ? "'".$row['subkey']."'" : "NULL")."," .
  2947. "'".$row['type']."','".$row['category']."'," .
  2948. "'$value','".$row['title']."'," .
  2949. "".(!empty($row['comment']) ? "'".$row['comment']."'" : "NULL").",".(!empty($row['scope']) ? "'".$row['scope']."'" : "NULL")."," .
  2950. "".(!empty($row['subkeytext'])?"'".$row['subkeytext']."'":"NULL").",$access_url)";
  2951. $res = Database::query($insert);
  2952. } else { // This setting does not exist
  2953. error_log(__FILE__.':'.__LINE__.': Attempting to update setting '.$var.' ('.$subvar.') which does not exist at all', 0);
  2954. }
  2955. } else {
  2956. // Other access url
  2957. if (!empty($subvar)) {
  2958. $select .= " AND subkey = '$subvar'";
  2959. }
  2960. if (!empty($cat)) {
  2961. $select .= " AND category = '$cat'";
  2962. }
  2963. $res = Database::query($select);
  2964. if (Database::num_rows($res) > 0) { // We have a setting for access_url 1, but none for the current one, so create one
  2965. $row = Database::fetch_array($res);
  2966. if ($row['access_url_changeable'] == 1) {
  2967. $insert = "INSERT INTO $t_settings " .
  2968. "(variable,subkey," .
  2969. "type,category," .
  2970. "selected_value,title," .
  2971. "comment,scope," .
  2972. "subkeytext,access_url, access_url_changeable)" .
  2973. " VALUES " .
  2974. "('".$row['variable']."',".
  2975. (!empty($row['subkey']) ? "'".$row['subkey']."'" : "NULL")."," .
  2976. "'".$row['type']."','".$row['category']."'," .
  2977. "'$value','".$row['title']."'," .
  2978. "".(!empty($row['comment']) ? "'".$row['comment']."'" : "NULL").",".
  2979. (!empty($row['scope']) ? "'".$row['scope']."'" : "NULL")."," .
  2980. "".(!empty($row['subkeytext']) ? "'".$row['subkeytext']."'" : "NULL").",$access_url,".$row['access_url_changeable'].")";
  2981. $res = Database::query($insert);
  2982. }
  2983. } else { // This setting does not exist
  2984. error_log(__FILE__.':'.__LINE__.': Attempting to update setting '.$var.' ('.$subvar.') which does not exist at all. The access_url is: '.$access_url.' ',0);
  2985. }
  2986. }
  2987. }
  2988. }
  2989. /**
  2990. * Sets a whole category of settings to one specific value
  2991. * @param string Category
  2992. * @param string Value
  2993. * @param int Access URL. Optional. Defaults to 1
  2994. * @param array Optional array of filters on field type
  2995. */
  2996. function api_set_settings_category($category, $value = null, $access_url = 1, $fieldtype = array()) {
  2997. if (empty($category)) { return false; }
  2998. $category = Database::escape_string($category);
  2999. $t_s = Database::get_main_table(TABLE_MAIN_SETTINGS_CURRENT);
  3000. $access_url = (int) $access_url;
  3001. if (empty($access_url)) { $access_url = 1; }
  3002. if (isset($value)) {
  3003. $value = Database::escape_string($value);
  3004. $sql = "UPDATE $t_s SET selected_value = '$value' WHERE category = '$category' AND access_url = $access_url";
  3005. if (is_array($fieldtype) && count($fieldtype)>0) {
  3006. $sql .= " AND ( ";
  3007. $i = 0;
  3008. foreach ($fieldtype as $type){
  3009. if ($i > 0) {
  3010. $sql .= ' OR ';
  3011. }
  3012. $type = Database::escape_string($type);
  3013. $sql .= " type='".$type."' ";
  3014. $i++;
  3015. }
  3016. $sql .= ")";
  3017. }
  3018. $res = Database::query($sql);
  3019. return $res !== false;
  3020. } else {
  3021. $sql = "UPDATE $t_s SET selected_value = NULL WHERE category = '$category' AND access_url = $access_url";
  3022. if (is_array($fieldtype) && count($fieldtype)>0) {
  3023. $sql .= " AND ( ";
  3024. $i = 0;
  3025. foreach ($fieldtype as $type){
  3026. if ($i > 0) {
  3027. $sql .= ' OR ';
  3028. }
  3029. $type = Database::escape_string($type);
  3030. $sql .= " type='".$type."' ";
  3031. $i++;
  3032. }
  3033. $sql .= ")";
  3034. }
  3035. $res = Database::query($sql);
  3036. return $res !== false;
  3037. }
  3038. }
  3039. /**
  3040. * Gets all available access urls in an array (as in the database)
  3041. * @return array An array of database records
  3042. */
  3043. function api_get_access_urls($from = 0, $to = 1000000, $order = 'url', $direction = 'ASC') {
  3044. $t_au = Database::get_main_table(TABLE_MAIN_ACCESS_URL);
  3045. $from = (int) $from;
  3046. $to = (int) $to;
  3047. $order = Database::escape_string($order);
  3048. $direction = Database::escape_string($direction);
  3049. $sql = "SELECT id, url, description, active, created_by, tms FROM $t_au ORDER BY $order $direction LIMIT $to OFFSET $from";
  3050. $res = Database::query($sql);
  3051. return Database::store_result($res);
  3052. }
  3053. /**
  3054. * Gets the access url info in an array
  3055. * @param id of the access url
  3056. * @return array Array with all the info (url, description, active, created_by, tms) from the access_url table
  3057. * @author Julio Montoya Armas
  3058. */
  3059. function api_get_access_url($id) {
  3060. global $_configuration;
  3061. $id = Database::escape_string(intval($id));
  3062. $result = array(); // Is this line necessary?
  3063. // calling the Database:: library dont work this is handmade
  3064. //$table_access_url = Database::get_main_table(TABLE_MAIN_ACCESS_URL);
  3065. $table = 'access_url';
  3066. $database = $_configuration['main_database'];
  3067. $table_access_url = "`".$database."`.`".$table."`";
  3068. $sql = "SELECT url, description, active, created_by, tms
  3069. FROM $table_access_url WHERE id = '$id' ";
  3070. $res = Database::query($sql);
  3071. $result = @Database::fetch_array($res);
  3072. return $result;
  3073. }
  3074. /**
  3075. * Adds an access URL into the database
  3076. * @param string URL
  3077. * @param string Description
  3078. * @param int Active (1= active, 0=disabled)
  3079. * @return int The new database id, or the existing database id if this url already exists
  3080. */
  3081. function api_add_access_url($u, $d = '', $a = 1) {
  3082. $t_au = Database::get_main_table(TABLE_MAIN_ACCESS_URL);
  3083. $u = Database::escape_string($u);
  3084. $d = Database::escape_string($d);
  3085. $a = (int) $a;
  3086. $sql = "SELECT id FROM $t_au WHERE url LIKE '$u'";
  3087. $res = Database::query($sql);
  3088. if ($res === false) {
  3089. // Problem querying the database - return false
  3090. return false;
  3091. }
  3092. if (Database::num_rows($res) > 0) {
  3093. return Database::result($res, 0, 'id');
  3094. }
  3095. $ui = api_get_user_id();
  3096. $sql = "INSERT INTO $t_au (url,description,active,created_by,tms) VALUES ('$u','$d',$a,$ui,'')";
  3097. $res = Database::query($sql);
  3098. return ($res === false) ? false : Database::insert_id();
  3099. }
  3100. /**
  3101. * Gets all the current settings for a specific access url
  3102. * @param string The category, if any, that we want to get
  3103. * @param string Whether we want a simple list (display a catgeory) or a grouped list (group by variable as in settings.php default). Values: 'list' or 'group'
  3104. * @param int Access URL's ID. Optional. Uses 1 by default, which is the unique URL
  3105. * @return array Array of database results for the current settings of the current access URL
  3106. */
  3107. function & api_get_settings($cat = null, $ordering = 'list', $access_url = 1, $url_changeable = 0) {
  3108. $t_cs = Database::get_main_table(TABLE_MAIN_SETTINGS_CURRENT);
  3109. $access_url = (int) $access_url;
  3110. $url_changeable_where = '';
  3111. if ($url_changeable == 1) {
  3112. $url_changeable_where= " AND access_url_changeable= '1' ";
  3113. }
  3114. if (empty($access_url)) { $access_url = 1; }
  3115. $sql = "SELECT id, variable, subkey, type, category, selected_value, title, comment, scope, subkeytext, access_url, access_url_changeable " .
  3116. " FROM $t_cs WHERE access_url = $access_url $url_changeable_where ";
  3117. if (!empty($cat)) {
  3118. $cat = Database::escape_string($cat);
  3119. $sql .= " AND category='$cat' ";
  3120. }
  3121. if ($ordering == 'group') {
  3122. $sql .= " GROUP BY variable ORDER BY id ASC";
  3123. } else {
  3124. $sql .= " ORDER BY 1,2 ASC";
  3125. }
  3126. return Database::store_result(Database::query($sql));
  3127. }
  3128. /**
  3129. * Gets the distinct settings categories
  3130. * @param array Array of strings giving the categories we want to exclude
  3131. * @param int Access URL. Optional. Defaults to 1
  3132. * @return array A list of categories
  3133. */
  3134. function & api_get_settings_categories($exceptions = array(), $access_url = 1) {
  3135. $access_url = (int) $access_url;
  3136. $t_cs = Database::get_main_table(TABLE_MAIN_SETTINGS_CURRENT);
  3137. $list = "'".implode("','",$exceptions)."'";
  3138. $sql = "SELECT DISTINCT category FROM $t_cs";
  3139. if ($list != "'',''" and $list != "''" and !empty($list)) {
  3140. $sql .= " WHERE category NOT IN ($list)";
  3141. }
  3142. return Database::store_result(Database::query($sql));
  3143. }
  3144. /**
  3145. * Deletes a setting
  3146. * @param string Variable
  3147. * @param string Subkey
  3148. * @param int Access URL
  3149. * @return boolean False on failure, true on success
  3150. */
  3151. function api_delete_setting($v, $s = null, $a = 1) {
  3152. if (empty($v)) { return false; }
  3153. $t_cs = Database::get_main_table(TABLE_MAIN_SETTINGS_CURRENT);
  3154. $v = Database::escape_string($v);
  3155. $a = (int) $a;
  3156. if (empty($a)) { $a = 1; }
  3157. if (!empty($s)) {
  3158. $s = Database::escape_string($s);
  3159. $sql = "DELETE FROM $t_cs WHERE variable = '$v' AND subkey = '$s' AND access_url = $a";
  3160. $r = Database::query($sql);
  3161. return $r;
  3162. }
  3163. $sql = "DELETE FROM $t_cs WHERE variable = '$v' AND access_url = $a";
  3164. $r = Database::query($sql);
  3165. return $r;
  3166. }
  3167. /**
  3168. * Deletes all the settings from one category
  3169. * @param string Category
  3170. * @param int Access URL
  3171. * @return boolean False on failure, true on success
  3172. */
  3173. function api_delete_category_settings($c, $a = 1) {
  3174. if (empty($c)) { return false; }
  3175. $t_cs = Database::get_main_table(TABLE_MAIN_SETTINGS_CURRENT);
  3176. $c = Database::escape_string($c);
  3177. $a = (int) $a;
  3178. if (empty($a)) { $a = 1; }
  3179. $sql = "DELETE FROM $t_cs WHERE category = '$c' AND access_url = $a";
  3180. $r = Database::query($sql);
  3181. return $r;
  3182. }
  3183. /**
  3184. * Sets a platform configuration setting to a given value
  3185. * @param string The value we want to record
  3186. * @param string The variable name we want to insert
  3187. * @param string The subkey for the variable we want to insert
  3188. * @param string The type for the variable we want to insert
  3189. * @param string The category for the variable we want to insert
  3190. * @param string The title
  3191. * @param string The comment
  3192. * @param string The scope
  3193. * @param string The subkey text
  3194. * @param int The access_url for which this parameter is valid
  3195. * @param int The changeability of this setting for non-master urls
  3196. * @return boolean true on success, false on failure
  3197. */
  3198. function api_add_setting($val, $var, $sk = null, $type = 'textfield', $c = null, $title = '', $com = '', $sc = null, $skt = null, $a = 1, $v = 0) {
  3199. if (empty($var) || !isset($val)) { return false; }
  3200. $t_settings = Database::get_main_table(TABLE_MAIN_SETTINGS_CURRENT);
  3201. $var = Database::escape_string($var);
  3202. $val = Database::escape_string($val);
  3203. $a = (int) $a;
  3204. if (empty($a)) { $a = 1; }
  3205. //check if this variable doesn't exist already
  3206. $select = "SELECT id FROM $t_settings WHERE variable = '$var' ";
  3207. if (!empty($sk)) {
  3208. $sk = Database::escape_string($sk);
  3209. $select .= " AND subkey = '$sk'";
  3210. }
  3211. if ($a > 1) {
  3212. $select .= " AND access_url = $a";
  3213. } else {
  3214. $select .= " AND access_url = 1 ";
  3215. }
  3216. $res = Database::query($select);
  3217. if (Database::num_rows($res) > 0) { //found item for this access_url
  3218. $row = Database::fetch_array($res);
  3219. return $row['id'];
  3220. }
  3221. //item not found for this access_url, we have to check if the whole thing is missing
  3222. //(in which case we ignore the insert) or if there *is* a record but just for access_url=1
  3223. $insert = "INSERT INTO $t_settings " .
  3224. "(variable,selected_value," .
  3225. "type,category," .
  3226. "subkey,title," .
  3227. "comment,scope," .
  3228. "subkeytext,access_url,access_url_changeable)" .
  3229. " VALUES ('$var','$val',";
  3230. if (isset($type)) {
  3231. $type = Database::escape_string($type);
  3232. $insert .= "'$type',";
  3233. } else {
  3234. $insert .= "NULL,";
  3235. }
  3236. if (isset($c)) {//category
  3237. $c = Database::escape_string($c);
  3238. $insert .= "'$c',";
  3239. } else {
  3240. $insert .= "NULL,";
  3241. }
  3242. if (isset($sk)) { //subkey
  3243. $sk = Database::escape_string($sk);
  3244. $insert .= "'$sk',";
  3245. } else {
  3246. $insert .= "NULL,";
  3247. }
  3248. if (isset($title)) {//title
  3249. $title = Database::escape_string($title);
  3250. $insert .= "'$title',";
  3251. } else {
  3252. $insert .= "NULL,";
  3253. }
  3254. if (isset($com)) {//comment
  3255. $com = Database::escape_string($com);
  3256. $insert .= "'$com',";
  3257. } else {
  3258. $insert .= "NULL,";
  3259. }
  3260. if (isset($sc)) {//scope
  3261. $sc = Database::escape_string($sc);
  3262. $insert .= "'$sc',";
  3263. } else {
  3264. $insert .= "NULL,";
  3265. }
  3266. if (isset($skt)) {//subkey text
  3267. $skt = Database::escape_string($skt);
  3268. $insert .= "'$skt',";
  3269. } else {
  3270. $insert .= "NULL,";
  3271. }
  3272. $insert .= "$a,$v)";
  3273. $res = Database::query($insert);
  3274. return $res;
  3275. }
  3276. /**
  3277. * Checks wether a user can or can't view the contents of a course.
  3278. *
  3279. * @param int $userid User id or NULL to get it from $_SESSION
  3280. * @param int $cid Course id to check whether the user is allowed.
  3281. * @return bool
  3282. */
  3283. function api_is_course_visible_for_user($userid = null, $cid = null) {
  3284. if ($userid == null) {
  3285. $userid = $_SESSION['_user']['user_id'];
  3286. }
  3287. if (empty($userid) || strval(intval($userid)) != $userid) {
  3288. if (api_is_anonymous()) {
  3289. $userid = api_get_anonymous_id();
  3290. } else {
  3291. return false;
  3292. }
  3293. }
  3294. $cid = Database::escape_string($cid);
  3295. global $is_platformAdmin;
  3296. $course_table = Database::get_main_table(TABLE_MAIN_COURSE);
  3297. $course_cat_table = Database::get_main_table(TABLE_MAIN_CATEGORY);
  3298. $sql = "SELECT
  3299. $course_table.category_code,
  3300. $course_table.visibility,
  3301. $course_table.code,
  3302. $course_cat_table.code
  3303. FROM $course_table
  3304. LEFT JOIN $course_cat_table
  3305. ON $course_table.category_code = $course_cat_table.code
  3306. WHERE
  3307. $course_table.code = '$cid'
  3308. LIMIT 1";
  3309. $result = Database::query($sql);
  3310. if (Database::num_rows($result) > 0) {
  3311. $visibility = Database::fetch_array($result);
  3312. $visibility = $visibility['visibility'];
  3313. } else {
  3314. $visibility = 0;
  3315. }
  3316. //shortcut permissions in case the visibility is "open to the world"
  3317. if ($visibility === COURSE_VISIBILITY_OPEN_WORLD) {
  3318. return true;
  3319. }
  3320. if (api_get_setting('use_session_mode') != 'true') {
  3321. $course_user_table = Database::get_main_table(TABLE_MAIN_COURSE_USER);
  3322. $sql = "SELECT tutor_id, status
  3323. FROM $course_user_table
  3324. WHERE user_id = '$userid' AND relation_type<>".COURSE_RELATION_TYPE_RRHH."
  3325. AND course_code = '$cid'
  3326. LIMIT 1";
  3327. $result = Database::query($sql);
  3328. if (Database::num_rows($result) > 0) {
  3329. // this user have a recorded state for this course
  3330. $cuData = Database::fetch_array($result);
  3331. $is_courseMember = true;
  3332. $is_courseTutor = ($cuData['tutor_id' ] == 1);
  3333. $is_courseAdmin = ($cuData['status'] == 1);
  3334. } else {
  3335. // this user has no status related to this course
  3336. $is_courseMember = false;
  3337. $is_courseAdmin = false;
  3338. $is_courseTutor = false;
  3339. }
  3340. $is_courseAdmin = ($is_courseAdmin || $is_platformAdmin);
  3341. } else {
  3342. $tbl_course_user = Database :: get_main_table(TABLE_MAIN_COURSE_USER);
  3343. $sql = "SELECT
  3344. tutor_id, status, role
  3345. FROM $tbl_course_user
  3346. WHERE
  3347. user_id = '$userid'
  3348. AND
  3349. relation_type <> '".COURSE_RELATION_TYPE_RRHH."'
  3350. AND
  3351. course_code = '$cid'
  3352. LIMIT 1";
  3353. $result = Database::query($sql);
  3354. if (Database::num_rows($result) > 0) {
  3355. // this user have a recorded state for this course
  3356. $cuData = Database::fetch_array($result);
  3357. $_courseUser['role'] = $cuData['role'];
  3358. $is_courseMember = true;
  3359. $is_courseTutor = ($cuData['tutor_id' ] == 1);
  3360. $is_courseAdmin = ($cuData['status'] == 1);
  3361. }
  3362. if (!$is_courseAdmin) {
  3363. // this user has no status related to this course
  3364. // is it the session coach or the session admin ?
  3365. $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
  3366. $tbl_session_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
  3367. $tbl_session_course_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
  3368. $sql = "SELECT
  3369. session.id_coach, session_admin_id, session.id
  3370. FROM
  3371. $tbl_session as session
  3372. INNER JOIN $tbl_session_course
  3373. ON session_rel_course.id_session = session.id
  3374. AND session_rel_course.course_code = '$cid'
  3375. LIMIT 1";
  3376. $result = Database::query($sql);
  3377. $row = Database::store_result($result);
  3378. if ($row[0]['id_coach'] == $userid) {
  3379. $_courseUser['role'] = 'Professor';
  3380. $is_courseMember = true;
  3381. $is_courseTutor = true;
  3382. $is_courseAdmin = false;
  3383. $is_courseCoach = true;
  3384. $is_sessionAdmin = false;
  3385. api_session_register('_courseUser');
  3386. }
  3387. elseif ($row[0]['session_admin_id'] == $userid) {
  3388. $_courseUser['role'] = 'Professor';
  3389. $is_courseMember = false;
  3390. $is_courseTutor = false;
  3391. $is_courseAdmin = false;
  3392. $is_courseCoach = false;
  3393. $is_sessionAdmin = true;
  3394. } else {
  3395. // Check if the current user is the course coach
  3396. $sql = "SELECT 1
  3397. FROM $tbl_session_course
  3398. WHERE session_rel_course.course_code = '$cid'
  3399. AND session_rel_course.id_coach = '$userid'
  3400. LIMIT 1";
  3401. $result = Database::query($sql);
  3402. if ($row = Database::fetch_array($result)) {
  3403. $_courseUser['role'] = 'Professor';
  3404. $is_courseMember = true;
  3405. $is_courseTutor = true;
  3406. $is_courseCoach = true;
  3407. $is_sessionAdmin = false;
  3408. $tbl_user = Database :: get_main_table(TABLE_MAIN_USER);
  3409. $sql = "SELECT status FROM $tbl_user
  3410. WHERE user_id = $userid LIMIT 1";
  3411. $result = Database::query($sql);
  3412. if (Database::result($result, 0, 0) == 1) {
  3413. $is_courseAdmin = true;
  3414. } else {
  3415. $is_courseAdmin = false;
  3416. }
  3417. } else {
  3418. // Check if the user is a student is this session
  3419. $sql = "SELECT id
  3420. FROM $tbl_session_course_user
  3421. WHERE id_user = '$userid'
  3422. AND course_code = '$cid'
  3423. LIMIT 1";
  3424. if (Database::num_rows($result) > 0) {
  3425. // this user have a recorded state for this course
  3426. while ($row = Database::fetch_array($result)) {
  3427. $is_courseMember = true;
  3428. $is_courseTutor = false;
  3429. $is_courseAdmin = false;
  3430. $is_sessionAdmin = false;
  3431. }
  3432. }
  3433. }
  3434. }
  3435. }
  3436. }
  3437. switch ($visibility) {
  3438. case COURSE_VISIBILITY_OPEN_WORLD:
  3439. return true;
  3440. case COURSE_VISIBILITY_OPEN_PLATFORM:
  3441. return isset($userid);
  3442. case COURSE_VISIBILITY_REGISTERED:
  3443. case COURSE_VISIBILITY_CLOSED:
  3444. return $is_platformAdmin || $is_courseMember || $is_courseAdmin;
  3445. }
  3446. return false;
  3447. }
  3448. /**
  3449. * Returns whether an element (forum, message, survey ...) belongs to a session or not
  3450. * @param String the tool of the element
  3451. * @param int the element id in database
  3452. * @param int the session_id to compare with element session id
  3453. * @return boolean true if the element is in the session, false else
  3454. */
  3455. function api_is_element_in_the_session($tool, $element_id, $session_id = null) {
  3456. if (is_null($session_id)) {
  3457. $session_id = intval($_SESSION['id_session']);
  3458. }
  3459. // Get information to build query depending of the tool
  3460. switch ($tool) {
  3461. case TOOL_SURVEY :
  3462. $table_tool = Database::get_course_table(TABLE_SURVEY);
  3463. $key_field = 'survey_id';
  3464. break;
  3465. case TOOL_ANNOUNCEMENT :
  3466. $table_tool = Database::get_course_table(TABLE_ANNOUNCEMENT);
  3467. $key_field = 'id';
  3468. break;
  3469. case TOOL_AGENDA :
  3470. $table_tool = Database::get_course_table(TABLE_AGENDA);
  3471. $key_field = 'id';
  3472. break;
  3473. case TOOL_GROUP :
  3474. $table_tool = Database::get_course_table(TABLE_GROUP);
  3475. $key_field = 'id';
  3476. break;
  3477. default: return false;
  3478. }
  3479. $sql = 'SELECT session_id FROM '.$table_tool.' WHERE '.$key_field.'='.intval($element_id);
  3480. $rs = Database::query($sql);
  3481. if ($element_session_id = Database::result($rs, 0, 0)) {
  3482. if ($element_session_id == intval($session_id)) { // The element belongs to the session
  3483. return true;
  3484. }
  3485. }
  3486. return false;
  3487. }
  3488. /**
  3489. * Replaces "forbidden" characters in a filename string.
  3490. *
  3491. * @author Hugues Peeters <peeters@ipm.ucl.ac.be>
  3492. * @author René Haentjens, UGent (RH)
  3493. * @author Ivan Tcholakov, JUN-2009. Transliteration functionality has been added.
  3494. * @param string $filename The filename string.
  3495. * @param string $strict (optional) When it is 'strict', all non-ASCII charaters will be replaced. Additional ASCII replacemets will be done too.
  3496. * @return string The cleaned filename.
  3497. */
  3498. function replace_dangerous_char($filename, $strict = 'loose') {
  3499. // Safe replacements for some non-letter characters.
  3500. static $search = array("\0", ' ', "\t", "\n", "\r", "\x0B", '/', "\\", '"', "'", '?', '*', '>', '<', '|', ':', '$', '(', ')', '^', '[', ']', '#', '+', '&', '%');
  3501. static $replace = array('', '_', '_', '_', '_', '_', '-', '-', '-', '_', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-');
  3502. // Encoding detection.
  3503. $encoding = api_detect_encoding($filename);
  3504. // Converting html-entities into encoded characters.
  3505. $filename = api_html_entity_decode($filename, ENT_QUOTES, $encoding);
  3506. // Transliteration to ASCII letters, they are not dangerous for filesystems.
  3507. $filename = api_transliterate($filename, 'x', $encoding);
  3508. // Trimming leading/trailing whitespace.
  3509. $filename = trim($filename);
  3510. // Trimming any leading/trailing dots.
  3511. $filename = trim($filename, '.');
  3512. $filename = trim($filename);
  3513. // Replacing remaining dangerous non-letter characters.
  3514. $filename = str_replace($search, $replace, $filename);
  3515. if ($strict == 'strict') {
  3516. $filename = str_replace('-', '_', $filename);
  3517. $filename = preg_replace('/[^0-9A-Za-z_.\-]/', '', $filename);
  3518. }
  3519. // Length is to be limited, so the file name to be acceptable by some operating systems.
  3520. $extension = (string)strrchr($filename, '.');
  3521. $extension_len = strlen($extension);
  3522. if ($extension_len > 0 && $extension_len < 250) {
  3523. $filename = substr($filename, 0, -$extension_len);
  3524. return substr($filename, 0, 250 - $extension_len).$extension;
  3525. }
  3526. return substr($filename, 0, 250);
  3527. }
  3528. /**
  3529. * Fixes the $_SERVER["REQUEST_URI"] that is empty in IIS6.
  3530. * @author Ivan Tcholakov, 28-JUN-2006.
  3531. */
  3532. function api_request_uri() {
  3533. if (!empty($_SERVER['REQUEST_URI'])) {
  3534. return $_SERVER['REQUEST_URI'];
  3535. }
  3536. $uri = $_SERVER['SCRIPT_NAME'];
  3537. if (!empty($_SERVER['QUERY_STRING'])) {
  3538. $uri .= '?'.$_SERVER['QUERY_STRING'];
  3539. }
  3540. $_SERVER['REQUEST_URI'] = $uri;
  3541. return $uri;
  3542. }
  3543. /**
  3544. * Creates the "include_path" php-setting, following the rule that
  3545. * PEAR packages of Chamilo should be read before other external packages.
  3546. * To be used in global.inc.php only.
  3547. * @author Ivan Tcholakov, 06-NOV-2008.
  3548. */
  3549. function api_create_include_path_setting() {
  3550. $include_path = ini_get('include_path');
  3551. if (!empty($include_path)) {
  3552. $include_path_array = explode(PATH_SEPARATOR, $include_path);
  3553. $dot_found = array_search('.', $include_path_array);
  3554. if ($dot_found !== false) {
  3555. $result = array();
  3556. foreach ($include_path_array as $path) {
  3557. $result[] = $path;
  3558. if ($path == '.') {
  3559. // The path of Chamilo PEAR packages is to be inserted after the current directory path.
  3560. $result[] = api_get_path(LIBRARY_PATH).'pear';
  3561. }
  3562. }
  3563. return implode(PATH_SEPARATOR, $result);
  3564. }
  3565. // Current directory is not listed in the include_path setting, low probability is here.
  3566. return api_get_path(LIBRARY_PATH).'pear'.PATH_SEPARATOR.$include_path;
  3567. }
  3568. // The include_path setting is empty, low probability is here.
  3569. return api_get_path(LIBRARY_PATH).'pear';
  3570. }
  3571. /** Gets the current access_url id of the Chamilo Platform
  3572. * @author Julio Montoya <gugli100@gmail.com>
  3573. * @return int access_url_id of the current Chamilo Installation
  3574. */
  3575. function api_get_current_access_url_id() {
  3576. $access_url_table = Database :: get_main_table(TABLE_MAIN_ACCESS_URL);
  3577. $path = api_get_path(WEB_PATH);
  3578. $sql = "SELECT id FROM $access_url_table WHERE url = '".$path."'";
  3579. $result = Database::query($sql);
  3580. if (Database::num_rows($result) > 0) {
  3581. $access_url_id = Database::result($result, 0, 0);
  3582. return $access_url_id;
  3583. }
  3584. return -1;
  3585. }
  3586. /** Gets the registered urls from a given user id
  3587. * @author Julio Montoya <gugli100@gmail.com>
  3588. * @return int user id
  3589. */
  3590. function api_get_access_url_from_user($user_id) {
  3591. $user_id = intval($user_id);
  3592. $table_url_rel_user = Database :: get_main_table(TABLE_MAIN_ACCESS_URL_REL_USER);
  3593. $table_url = Database :: get_main_table(TABLE_MAIN_ACCESS_URL);
  3594. $sql = "SELECT access_url_id FROM $table_url_rel_user url_rel_user INNER JOIN $table_url u
  3595. ON (url_rel_user.access_url_id = u.id)
  3596. WHERE user_id = ".Database::escape_string($user_id);
  3597. $result = Database::query($sql);
  3598. $url_list = array();
  3599. while ($row = Database::fetch_array($result, 'ASSOC')) {
  3600. $url_list[] = $row['access_url_id'];
  3601. }
  3602. return $url_list;
  3603. }
  3604. /**
  3605. * Gets the status of a user in a course
  3606. * @param int user_id
  3607. * @param string course_code
  3608. * @return int user status
  3609. */
  3610. function api_get_status_of_user_in_course ($user_id, $course_code) {
  3611. $tbl_rel_course_user = Database :: get_main_table(TABLE_MAIN_COURSE_USER);
  3612. if (!empty($user_id) && !empty($course_code)) {
  3613. $user_id = Database::escape_string(intval($user_id));
  3614. $course_code = Database::escape_string($course_code);
  3615. $sql = 'SELECT status FROM '.$tbl_rel_course_user.'
  3616. WHERE user_id='.$user_id.' AND course_code="'.$course_code.'";';
  3617. $result = Database::query($sql);
  3618. $row_status = Database::fetch_array($result, 'ASSOC');
  3619. return $row_status['status'];
  3620. } else {
  3621. return 0;
  3622. }
  3623. }
  3624. /**
  3625. * Checks whether the curent user is in a course or not.
  3626. *
  3627. * @param string The course code - optional (takes it from session if not given)
  3628. * @return boolean
  3629. * @author Yannick Warnier <yannick.warnier@dokeos.com>
  3630. */
  3631. function api_is_in_course($course_code = null) {
  3632. if (isset($_SESSION['_course']['sysCode'])) {
  3633. if (!empty($course_code)) {
  3634. return $course_code == $_SESSION['_course']['sysCode'];
  3635. }
  3636. return true;
  3637. }
  3638. return false;
  3639. }
  3640. /**
  3641. * Checks whether the curent user is in a group or not.
  3642. *
  3643. * @param string The group id - optional (takes it from session if not given)
  3644. * @param string The course code - optional (no additional check by course if course code is not given)
  3645. * @return boolean
  3646. * @author Ivan Tcholakov
  3647. */
  3648. function api_is_in_group($group_id = null, $course_code = null) {
  3649. if (!empty($course_code)) {
  3650. if (isset($_SESSION['_course']['sysCode'])) {
  3651. if ($course_code != $_SESSION['_course']['sysCode']) return false;
  3652. } else {
  3653. return false;
  3654. }
  3655. }
  3656. if (isset($_SESSION['_gid']) && $_SESSION['_gid'] != '') {
  3657. if (!empty($group_id)) {
  3658. return $group_id == $_SESSION['_gid'];
  3659. } else {
  3660. return true;
  3661. }
  3662. }
  3663. return false;
  3664. }
  3665. /**
  3666. * This function gets the hash in md5 or sha1 (it depends in the platform config) of a given password
  3667. * @param string password
  3668. * @return string password with the applied hash
  3669. */
  3670. function api_get_encrypted_password($password, $salt = '') {
  3671. global $userPasswordCrypted;
  3672. switch ($userPasswordCrypted){
  3673. case 'md5':
  3674. return empty($salt) ? md5($password) : md5($password.$salt);
  3675. case 'sha1':
  3676. return empty($salt) ? sha1($password) : sha1($password.$salt);
  3677. case 'none':
  3678. return $password;
  3679. default:
  3680. return empty($salt) ? md5($password) : md5($password.$salt);
  3681. }
  3682. }
  3683. /**
  3684. * Checks whether a secret key is valid
  3685. * @param string $original_key_secret - secret key from (webservice) client
  3686. * @param string $security_key - security key from dokeos
  3687. * @return boolean - true if secret key is valid, false otherwise
  3688. */
  3689. function api_is_valid_secret_key($original_key_secret, $security_key) {
  3690. global $_configuration;
  3691. return $original_key_secret == sha1($security_key);
  3692. }
  3693. /**
  3694. * Checks whether a user is into course
  3695. * @param string $course_id - the course id
  3696. * @param string $user_id - the user id
  3697. */
  3698. function api_is_user_of_course($course_id, $user_id) {
  3699. $tbl_course_rel_user = Database::get_main_table(TABLE_MAIN_COURSE_USER);
  3700. $sql = 'SELECT user_id FROM '.$tbl_course_rel_user.' WHERE course_code="'.Database::escape_string($course_id).'" AND user_id="'.Database::escape_string($user_id).'" AND relation_type<>'.COURSE_RELATION_TYPE_RRHH.' ';
  3701. $result = Database::query($sql);
  3702. return Database::num_rows($result) == 1;
  3703. }
  3704. /**
  3705. * Checks whether the server's operating system is Windows (TM).
  3706. * @return boolean - true if the operating system is Windows, false otherwise
  3707. */
  3708. function api_is_windows_os() {
  3709. if (function_exists('php_uname')) {
  3710. // php_uname() exists as of PHP 4.0.2, according to the documentation.
  3711. // We expect that this function will always work for Chamilo 1.8.x.
  3712. $os = php_uname();
  3713. }
  3714. // The following methods are not needed, but let them stay, just in case.
  3715. elseif (isset($_ENV['OS'])) {
  3716. // Sometimes $_ENV['OS'] may not be present (bugs?)
  3717. $os = $_ENV['OS'];
  3718. }
  3719. elseif (defined('PHP_OS')) {
  3720. // PHP_OS means on which OS PHP was compiled, this is why
  3721. // using PHP_OS is the last choice for detection.
  3722. $os = PHP_OS;
  3723. } else {
  3724. return false;
  3725. }
  3726. return strtolower(substr((string)$os, 0, 3 )) == 'win';
  3727. }
  3728. /**
  3729. * This function informs whether the sent request is XMLHttpRequest
  3730. */
  3731. function api_is_xml_http_request() {
  3732. return isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest';
  3733. }
  3734. /**
  3735. * Substitute for json_encode function for PHP version < 5.2.
  3736. *
  3737. * The following function has been adopted from Drupal's "Image Browser" project,
  3738. * @link http://drupal.org/project/imagebrowser
  3739. * version 6.x-2.x-dev, 2010-Mar-11,
  3740. * @link http://ftp.drupal.org/files/projects/imagebrowser-6.x-2.x-dev.tar.gz
  3741. */
  3742. if (!function_exists('json_encode')) {
  3743. function json_encode($a = false) {
  3744. if (is_null($a)) return 'null';
  3745. if ($a === false) return 'false';
  3746. if ($a === true) return 'true';
  3747. if (is_scalar($a)) {
  3748. if (is_float($a)) {
  3749. // Always use "." for floats.
  3750. return floatval(str_replace(",", ".", strval($a)));
  3751. }
  3752. if (is_string($a)) {
  3753. static $json_replaces = array(array("\\", "/", "\n", "\t", "\r", "\b", "\f", '"'), array('\\\\', '\\/', '\\n', '\\t', '\\r', '\\b', '\\f', '\"'));
  3754. return '"' . str_replace($json_replaces[0], $json_replaces[1], $a) . '"';
  3755. }
  3756. else
  3757. return $a;
  3758. }
  3759. $is_list = true;
  3760. for ($i = 0, reset($a); $i < count($a); $i++, next($a)) {
  3761. if (key($a) !== $i) {
  3762. $is_list = false;
  3763. break;
  3764. }
  3765. }
  3766. $result = array();
  3767. if ($is_list) {
  3768. foreach ($a as $v) $result[] = json_encode($v);
  3769. return '[' . join(',', $result) . ']';
  3770. }
  3771. else {
  3772. foreach ($a as $k => $v) $result[] = json_encode($k).':'.json_encode($v);
  3773. return '{' . join(',', $result) . '}';
  3774. }
  3775. }
  3776. }
  3777. /**
  3778. * This wrapper function has been implemented for avoiding some known problems about the function getimagesize().
  3779. * @link http://php.net/manual/en/function.getimagesize.php
  3780. * @link http://www.dokeos.com/forum/viewtopic.php?t=12345
  3781. * @link http://www.dokeos.com/forum/viewtopic.php?t=16355
  3782. */
  3783. function api_getimagesize($path) {
  3784. return @getimagesize(preg_match(VALID_WEB_PATH, $path) ? (api_is_internal_path($path) ? api_get_path(TO_SYS, $path) : $path) : $path);
  3785. }
  3786. /**
  3787. * This function resizes an image, with preserving its proportions (or aspect ratio).
  3788. * @author Ivan Tcholakov, MAY-2009.
  3789. * @param int $image System path or URL of the image
  3790. * @param int $target_width Targeted width
  3791. * @param int $target_height Targeted height
  3792. * @return array Calculated new width and height
  3793. */
  3794. function api_resize_image($image, $target_width, $target_height) {
  3795. $image_properties = api_getimagesize($image);
  3796. $image_width = $image_properties[0];
  3797. $image_height = $image_properties[1];
  3798. return api_calculate_image_size($image_width, $image_height, $target_width, $target_height);
  3799. }
  3800. /**
  3801. * This function calculates new image size, with preserving image's proportions (or aspect ratio).
  3802. * @author Ivan Tcholakov, MAY-2009.
  3803. * @author The initial idea has been taken from code by Patrick Cool, MAY-2004.
  3804. * @param int $image_width Initial width
  3805. * @param int $image_height Initial height
  3806. * @param int $target_width Targeted width
  3807. * @param int $target_height Targeted height
  3808. * @return array Calculated new width and height
  3809. */
  3810. function api_calculate_image_size($image_width, $image_height, $target_width, $target_height) {
  3811. // Only maths is here.
  3812. $result = array('width' => $image_width, 'height' => $image_height);
  3813. if ($image_width <= 0 || $image_height <= 0) {
  3814. return $result;
  3815. }
  3816. $resize_factor_width = $target_width / $image_width;
  3817. $resize_factor_height = $target_height / $image_height;
  3818. $delta_width = $target_width - $image_width * $resize_factor_height;
  3819. $delta_height = $target_height - $image_height * $resize_factor_width;
  3820. if ($delta_width > $delta_height) {
  3821. $result['width'] = ceil($image_width * $resize_factor_height);
  3822. $result['height'] = ceil($image_height * $resize_factor_height);
  3823. }
  3824. elseif ($delta_width < $delta_height) {
  3825. $result['width'] = ceil($image_width * $resize_factor_width);
  3826. $result['height'] = ceil($image_height * $resize_factor_width);
  3827. }
  3828. else {
  3829. $result['width'] = ceil($target_width);
  3830. $result['height'] = ceil($target_height);
  3831. }
  3832. return $result;
  3833. }
  3834. /**
  3835. * Returns a list of Chamilo's tools or
  3836. * checks whether a given identificator is a valid Chamilo's tool.
  3837. * @author Isaac flores paz <florespaz@bidsoftperu.com>
  3838. * @param string The tool name to filter
  3839. * @return mixed Filtered string or array
  3840. */
  3841. function api_get_tools_lists($my_tool = null) {
  3842. $tools_list = array(
  3843. TOOL_DOCUMENT, TOOL_THUMBNAIL, TOOL_HOTPOTATOES,
  3844. TOOL_CALENDAR_EVENT, TOOL_LINK, TOOL_COURSE_DESCRIPTION, TOOL_SEARCH,
  3845. TOOL_LEARNPATH, TOOL_ANNOUNCEMENT, TOOL_FORUM, TOOL_THREAD, TOOL_POST,
  3846. TOOL_DROPBOX, TOOL_QUIZ, TOOL_USER, TOOL_GROUP, TOOL_BLOGS, TOOL_CHAT,
  3847. TOOL_CONFERENCE, TOOL_STUDENTPUBLICATION, TOOL_TRACKING, TOOL_HOMEPAGE_LINK,
  3848. TOOL_COURSE_SETTING, TOOL_BACKUP, TOOL_COPY_COURSE_CONTENT, TOOL_RECYCLE_COURSE,
  3849. TOOL_COURSE_HOMEPAGE, TOOL_COURSE_RIGHTS_OVERVIEW, TOOL_UPLOAD, TOOL_COURSE_MAINTENANCE,
  3850. TOOL_VISIO, TOOL_VISIO_CONFERENCE, TOOL_VISIO_CLASSROOM, TOOL_SURVEY, TOOL_WIKI,
  3851. TOOL_GLOSSARY, TOOL_GRADEBOOK, TOOL_NOTEBOOK, TOOL_ATTENDANCE, TOOL_COURSE_PROGRESS
  3852. );
  3853. if (empty($my_tool)) {
  3854. return $tools_list;
  3855. }
  3856. return in_array($my_tool, $tools_list) ? $my_tool : '';
  3857. }
  3858. /**
  3859. * Checks whether we already approved the last version term and condition
  3860. * @param int user id
  3861. * @return bool true if we pass false otherwise
  3862. */
  3863. function api_check_term_condition($user_id) {
  3864. if (api_get_setting('allow_terms_conditions') == 'true') {
  3865. require_once api_get_path(LIBRARY_PATH).'legal.lib.php';
  3866. $t_uf = Database::get_main_table(TABLE_MAIN_USER_FIELD);
  3867. $t_ufv = Database::get_main_table(TABLE_MAIN_USER_FIELD_VALUES);
  3868. //check if exists terms and conditions
  3869. if (LegalManager::count() == 0) {
  3870. return true;
  3871. }
  3872. // Check the last user version_id passed
  3873. $sqlv = "SELECT field_value FROM $t_ufv ufv inner join $t_uf uf on ufv.field_id= uf.id
  3874. WHERE field_variable = 'legal_accept' AND user_id = ".intval($user_id);
  3875. $resv = Database::query($sqlv);
  3876. if (Database::num_rows($resv) > 0) {
  3877. $rowv = Database::fetch_row($resv);
  3878. $rowv = $rowv[0];
  3879. $user_conditions = explode(':', $rowv);
  3880. $version = $user_conditions[0];
  3881. $lang_id = $user_conditions[1];
  3882. $real_version = LegalManager::get_last_version($lang_id);
  3883. return $version >= $real_version;
  3884. }
  3885. return false;
  3886. }
  3887. return false;
  3888. }
  3889. /**
  3890. * Gets all information of a tool into course
  3891. * @param int The tool id
  3892. * @return array
  3893. */
  3894. function api_get_tool_information($tool_id) {
  3895. $t_tool = Database::get_course_table(TABLE_TOOL_LIST);
  3896. $sql = 'SELECT * FROM '.$t_tool.' WHERE id="'.Database::escape_string($tool_id).'"';
  3897. $rs = Database::query($sql);
  3898. return Database::fetch_array($rs);
  3899. }
  3900. /**
  3901. * Gets all information of a tool into course
  3902. * @param int The tool id
  3903. * @return array
  3904. */
  3905. function api_get_tool_information_by_name($name) {
  3906. $t_tool = Database::get_course_table(TABLE_TOOL_LIST);
  3907. $sql = 'SELECT * FROM '.$t_tool.' WHERE name="'.Database::escape_string($name).'"';
  3908. $rs = Database::query($sql);
  3909. return Database::fetch_array($rs, 'ASSOC');
  3910. }
  3911. /* DEPRECATED FUNCTIONS */
  3912. /**
  3913. * Deprecated, use api_trunc_str() instead.
  3914. */
  3915. function shorten($input, $length = 15, $encoding = null) {
  3916. $length = intval($length);
  3917. if (!$length) {
  3918. $length = 15;
  3919. }
  3920. return api_trunc_str($input, $length, '...', false, $encoding);
  3921. }
  3922. /**
  3923. * DEPRECATED, use api_get_setting instead
  3924. */
  3925. function get_setting($variable, $key = NULL) {
  3926. global $_setting;
  3927. return api_get_setting($variable, $key);
  3928. }
  3929. /**
  3930. * @deprecated, use api_is_allowed_to_edit() instead
  3931. */
  3932. function is_allowed_to_edit() {
  3933. return api_is_allowed_to_edit();
  3934. }
  3935. /**
  3936. * @deprecated 19-SEP-2009: Use api_get_path(TO_SYS, $url) instead.
  3937. */
  3938. function api_url_to_local_path($url) {
  3939. return api_get_path(TO_SYS, $url);
  3940. }
  3941. /**
  3942. * @deprecated 27-SEP-2009: Use Database::store_result($result) instead.
  3943. */
  3944. function api_store_result($result) {
  3945. return Database::store_result($result);
  3946. }
  3947. /**
  3948. * @deprecated 28-SEP-2009: Use Database::query($query, $file, $line) instead.
  3949. */
  3950. function api_sql_query($query, $file = '', $line = 0) {
  3951. return Database::query($query, $file, $line);
  3952. }
  3953. /**
  3954. * @deprecated 25-JAN-2010: See api_mail() and api_mail_html(), mail.lib.inc.php
  3955. *
  3956. * Send an email.
  3957. *
  3958. * Wrapper function for the standard php mail() function. Change this function
  3959. * to your needs. The parameters must follow the same rules as the standard php
  3960. * mail() function. Please look at the documentation on http://php.net/manual/en/function.mail.php
  3961. * @param string $to
  3962. * @param string $subject
  3963. * @param string $message
  3964. * @param string $additional_headers
  3965. * @param string $additional_parameters
  3966. * @author Ivan Tcholakov, 04-OCT-2009, a reworked version of this function.
  3967. * @link http://www.dokeos.com/forum/viewtopic.php?t=15557
  3968. */
  3969. function api_send_mail($to, $subject, $message, $additional_headers = null, $additional_parameters = null) {
  3970. require_once api_get_path(LIBRARY_PATH).'phpmailer/class.phpmailer.php';
  3971. require_once api_get_path(CONFIGURATION_PATH).'mail.conf.php';
  3972. if (empty($platform_email['SMTP_FROM_NAME'])) {
  3973. $platform_email['SMTP_FROM_NAME'] = api_get_person_name(api_get_setting('administratorName'), api_get_setting('administratorSurname'), null, PERSON_NAME_EMAIL_ADDRESS);
  3974. }
  3975. if (empty($platform_email['SMTP_FROM_EMAIL'])) {
  3976. $platform_email['SMTP_FROM_EMAIL'] = api_get_setting('emailAdministrator');
  3977. }
  3978. $matches = array();
  3979. if (preg_match('/([^<]*)<(.+)>/si', $to, $matches)) {
  3980. $recipient_name = trim($matches[1]);
  3981. $recipient_email = trim($matches[2]);
  3982. } else {
  3983. $recipient_name = '';
  3984. $recipient_email = trim($to);
  3985. }
  3986. $sender_name = '';
  3987. $sender_email = '';
  3988. $extra_headers = $additional_headers;
  3989. //regular expression to test for valid email address
  3990. // this should actually be revised to use the complete RFC3696 description
  3991. // http://tools.ietf.org/html/rfc3696#section-3
  3992. $regexp = "^[0-9a-z_\.+-]+@(([0-9]{1,3}\.){3}[0-9]{1,3}|([0-9a-z][0-9a-z-]*[0-9a-z]\.)+[a-z]{2,3})$";
  3993. $mail = new PHPMailer();
  3994. $mail->CharSet = $platform_email['SMTP_CHARSET'];
  3995. $mail->Mailer = $platform_email['SMTP_MAILER'];
  3996. $mail->Host = $platform_email['SMTP_HOST'];
  3997. $mail->Port = $platform_email['SMTP_PORT'];
  3998. if ($platform_email['SMTP_AUTH']) {
  3999. $mail->SMTPAuth = 1;
  4000. $mail->Username = $platform_email['SMTP_USER'];
  4001. $mail->Password = $platform_email['SMTP_PASS'];
  4002. }
  4003. $mail->Priority = 3; // 5=low, 1=high
  4004. $mail->AddCustomHeader('Errors-To: '.$platform_email['SMTP_FROM_EMAIL']);
  4005. $mail->IsHTML(0);
  4006. $mail->SMTPKeepAlive = true;
  4007. // attachments
  4008. // $mail->AddAttachment($path);
  4009. // $mail->AddAttachment($path, $filename);
  4010. if ($sender_email != '') {
  4011. $mail->From = $sender_email;
  4012. $mail->Sender = $sender_email;
  4013. //$mail->ConfirmReadingTo = $sender_email; //Disposition-Notification
  4014. } else {
  4015. $mail->From = $platform_email['SMTP_FROM_EMAIL'];
  4016. $mail->Sender = $platform_email['SMTP_FROM_EMAIL'];
  4017. //$mail->ConfirmReadingTo = $platform_email['SMTP_FROM_EMAIL']; //Disposition-Notification
  4018. }
  4019. if ($sender_name != '') {
  4020. $mail->FromName = $sender_name;
  4021. } else {
  4022. $mail->FromName = $platform_email['SMTP_FROM_NAME'];
  4023. }
  4024. $mail->Subject = $subject;
  4025. $mail->Body = $message;
  4026. //only valid address
  4027. if (eregi( $regexp, $recipient_email )) {
  4028. $mail->AddAddress($recipient_email, $recipient_name);
  4029. }
  4030. if ($extra_headers != '') {
  4031. $mail->AddCustomHeader($extra_headers);
  4032. }
  4033. //send mail
  4034. if (!$mail->Send()) {
  4035. return 0;
  4036. }
  4037. // Clear all addresses
  4038. $mail->ClearAddresses();
  4039. return 1;
  4040. }