extra_field.lib.php 91 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287
  1. <?php
  2. /* For licensing terms, see /license.txt */
  3. use Chamilo\CoreBundle\Entity\ExtraField as EntityExtraField;
  4. /**
  5. * Class ExtraField
  6. */
  7. class ExtraField extends Model
  8. {
  9. public $columns = array(
  10. 'id',
  11. 'field_type',
  12. 'variable',
  13. 'display_text',
  14. 'default_value',
  15. 'field_order',
  16. 'visible',
  17. 'changeable',
  18. 'filter',
  19. 'extra_field_type',
  20. /* Enable this when field_loggeable is introduced as a table field (2.0)
  21. 'field_loggeable',
  22. */
  23. 'created_at'
  24. );
  25. public $ops = array(
  26. 'eq' => '=', //equal
  27. 'ne' => '<>', //not equal
  28. 'lt' => '<', //less than
  29. 'le' => '<=', //less than or equal
  30. 'gt' => '>', //greater than
  31. 'ge' => '>=', //greater than or equal
  32. 'bw' => 'LIKE', //begins with
  33. 'bn' => 'NOT LIKE', //doesn't begin with
  34. 'in' => 'LIKE', //is in
  35. 'ni' => 'NOT LIKE', //is not in
  36. 'ew' => 'LIKE', //ends with
  37. 'en' => 'NOT LIKE', //doesn't end with
  38. 'cn' => 'LIKE', //contains
  39. 'nc' => 'NOT LIKE' //doesn't contain
  40. );
  41. const FIELD_TYPE_TEXT = 1;
  42. const FIELD_TYPE_TEXTAREA = 2;
  43. const FIELD_TYPE_RADIO = 3;
  44. const FIELD_TYPE_SELECT = 4;
  45. const FIELD_TYPE_SELECT_MULTIPLE = 5;
  46. const FIELD_TYPE_DATE = 6;
  47. const FIELD_TYPE_DATETIME = 7;
  48. const FIELD_TYPE_DOUBLE_SELECT = 8;
  49. const FIELD_TYPE_DIVIDER = 9;
  50. const FIELD_TYPE_TAG = 10;
  51. const FIELD_TYPE_TIMEZONE = 11;
  52. const FIELD_TYPE_SOCIAL_PROFILE = 12;
  53. const FIELD_TYPE_CHECKBOX = 13;
  54. const FIELD_TYPE_MOBILE_PHONE_NUMBER = 14;
  55. const FIELD_TYPE_INTEGER = 15;
  56. const FIELD_TYPE_FILE_IMAGE = 16;
  57. const FIELD_TYPE_FLOAT = 17;
  58. const FIELD_TYPE_FILE = 18;
  59. const FIELD_TYPE_VIDEO_URL = 19;
  60. const FIELD_TYPE_LETTERS_ONLY = 20;
  61. const FIELD_TYPE_ALPHANUMERIC = 21;
  62. const FIELD_TYPE_LETTERS_SPACE = 22;
  63. const FIELD_TYPE_ALPHANUMERIC_SPACE = 23;
  64. public $type = 'user';
  65. public $pageName;
  66. public $pageUrl;
  67. public $extraFieldType = 0;
  68. /**
  69. * @param string $type
  70. */
  71. public function __construct($type)
  72. {
  73. $this->type = $type;
  74. $this->table = Database::get_main_table(TABLE_EXTRA_FIELD);
  75. $this->table_field_options = Database::get_main_table(TABLE_EXTRA_FIELD_OPTIONS);
  76. $this->table_field_values = Database::get_main_table(TABLE_EXTRA_FIELD_VALUES);
  77. $this->handler_id = 'item_id';
  78. switch ($this->type) {
  79. case 'calendar_event':
  80. $this->extraFieldType = EntityExtraField::CALENDAR_FIELD_TYPE;
  81. break;
  82. case 'course':
  83. $this->extraFieldType = EntityExtraField::COURSE_FIELD_TYPE;
  84. $this->primaryKey = 'id';
  85. break;
  86. case 'user':
  87. $this->extraFieldType = EntityExtraField::USER_FIELD_TYPE;
  88. $this->primaryKey = 'id';
  89. break;
  90. case 'session':
  91. $this->extraFieldType = EntityExtraField::SESSION_FIELD_TYPE;
  92. $this->primaryKey = 'id';
  93. break;
  94. case 'question':
  95. $this->extraFieldType = EntityExtraField::QUESTION_FIELD_TYPE;
  96. break;
  97. case 'lp':
  98. $this->extraFieldType = EntityExtraField::LP_FIELD_TYPE;
  99. break;
  100. case 'lp_item':
  101. $this->extraFieldType = EntityExtraField::LP_ITEM_FIELD_TYPE;
  102. break;
  103. case 'skill':
  104. $this->extraFieldType = EntityExtraField::SKILL_FIELD_TYPE;
  105. break;
  106. case 'work':
  107. $this->extraFieldType = EntityExtraField::WORK_FIELD_TYPE;
  108. break;
  109. case 'survey':
  110. $this->extraFieldType = EntityExtraField::SURVEY_FIELD_TYPE;
  111. break;
  112. }
  113. $this->pageUrl = 'extra_fields.php?type='.$this->type;
  114. // Example QuestionFields
  115. $this->pageName = get_lang(ucwords($this->type).'Fields');
  116. }
  117. /**
  118. * @return int
  119. */
  120. public function getExtraFieldType()
  121. {
  122. return $this->extraFieldType;
  123. }
  124. /**
  125. * @return array
  126. */
  127. public static function getValidExtraFieldTypes()
  128. {
  129. return array(
  130. 'user',
  131. 'course',
  132. 'session',
  133. 'question',
  134. 'lp',
  135. 'calendar_event',
  136. 'lp_item',
  137. 'skill',
  138. 'work',
  139. 'survey'
  140. );
  141. }
  142. /**
  143. * @return int
  144. */
  145. public function get_count()
  146. {
  147. $em = Database::getManager();
  148. $query = $em->getRepository('ChamiloCoreBundle:ExtraField')->createQueryBuilder('e');
  149. $query->select('count(e.id)');
  150. $query->where('e.extraFieldType = :type');
  151. $query->setParameter('type', $this->getExtraFieldType());
  152. return $query->getQuery()->getScalarResult();
  153. }
  154. /**
  155. * @param string $sidx
  156. * @param string $sord
  157. * @param int $start
  158. * @param int $limit
  159. *
  160. * @return array
  161. */
  162. public function getAllGrid($sidx, $sord, $start, $limit)
  163. {
  164. switch ($sidx) {
  165. case 'field_order':
  166. $sidx = 'e.fieldOrder';
  167. break;
  168. case 'variable':
  169. $sidx = 'e.variable';
  170. break;
  171. case 'display_text':
  172. $sidx = 'e.displayText';
  173. break;
  174. case 'changeable':
  175. $sidx = 'e.changeable';
  176. break;
  177. case 'visible':
  178. $sidx = 'e.visible';
  179. break;
  180. case 'filter':
  181. $sidx = 'e.filter';
  182. break;
  183. case 'display_text':
  184. $sidx = 'e.fieldType';
  185. break;
  186. }
  187. $em = Database::getManager();
  188. $query = $em->getRepository('ChamiloCoreBundle:ExtraField')->createQueryBuilder('e');
  189. $query->select('e')
  190. ->where('e.extraFieldType = :type')
  191. ->setParameter('type', $this->getExtraFieldType())
  192. ->orderBy($sidx, $sord)
  193. ->setFirstResult($start)
  194. ->setMaxResults($limit);
  195. //echo $query->getQuery()->getSQL();
  196. return $query->getQuery()->getArrayResult();
  197. }
  198. /**
  199. * @param array $conditions
  200. * @param null $order_field_options_by
  201. *
  202. * @return array
  203. */
  204. public function get_all($conditions = array(), $order_field_options_by = null)
  205. {
  206. $conditions = Database::parse_conditions(array('where' => $conditions));
  207. if (empty($conditions)) {
  208. $conditions .= " WHERE extra_field_type = ".$this->extraFieldType;
  209. } else {
  210. $conditions .= " AND extra_field_type = ".$this->extraFieldType;
  211. }
  212. $sql = "SELECT * FROM $this->table
  213. $conditions
  214. ORDER BY field_order ASC
  215. ";
  216. $result = Database::query($sql);
  217. $extraFields = Database::store_result($result, 'ASSOC');
  218. $option = new ExtraFieldOption($this->type);
  219. if (!empty($extraFields)) {
  220. foreach ($extraFields as &$extraField) {
  221. $extraField['options'] = $option->get_field_options_by_field(
  222. $extraField['id'],
  223. false,
  224. $order_field_options_by
  225. );
  226. }
  227. }
  228. return $extraFields;
  229. }
  230. /**
  231. * @param string $variable
  232. *
  233. * @return array|bool
  234. */
  235. public function get_handler_field_info_by_field_variable($variable)
  236. {
  237. $variable = Database::escape_string($variable);
  238. $sql = "SELECT * FROM {$this->table}
  239. WHERE
  240. variable = '$variable' AND
  241. extra_field_type = $this->extraFieldType";
  242. $result = Database::query($sql);
  243. if (Database::num_rows($result)) {
  244. $row = Database::fetch_array($result, 'ASSOC');
  245. // All the options of the field
  246. $sql = "SELECT * FROM $this->table_field_options
  247. WHERE field_id='".intval($row['id'])."'
  248. ORDER BY option_order ASC";
  249. $result = Database::query($sql);
  250. while ($option = Database::fetch_array($result)) {
  251. $row['options'][$option['id']] = $option;
  252. }
  253. return $row;
  254. } else {
  255. return false;
  256. }
  257. }
  258. /**
  259. * @param int $fieldId
  260. *
  261. * @return array|bool
  262. */
  263. public function getFieldInfoByFieldId($fieldId)
  264. {
  265. $fieldId = intval($fieldId);
  266. $sql = "SELECT * FROM {$this->table}
  267. WHERE
  268. field_id = '$fieldId' AND
  269. extra_field_type = $this->extraFieldType";
  270. $result = Database::query($sql);
  271. if (Database::num_rows($result)) {
  272. $row = Database::fetch_array($result, 'ASSOC');
  273. // All the options of the field
  274. $sql = "SELECT * FROM $this->table_field_options
  275. WHERE field_id='".$fieldId."'
  276. ORDER BY option_order ASC";
  277. $result = Database::query($sql);
  278. while ($option = Database::fetch_array($result)) {
  279. $row['options'][$option['id']] = $option;
  280. }
  281. return $row;
  282. } else {
  283. return false;
  284. }
  285. }
  286. /**
  287. * @return int
  288. */
  289. public function get_max_field_order()
  290. {
  291. $sql = "SELECT MAX(field_order)
  292. FROM {$this->table}
  293. WHERE
  294. extra_field_type = '.$this->extraFieldType.'";
  295. $res = Database::query($sql);
  296. $order = 0;
  297. if (Database::num_rows($res) > 0) {
  298. $row = Database::fetch_row($res);
  299. $order = $row[0] + 1;
  300. }
  301. return $order;
  302. }
  303. /**
  304. * @param string $handler
  305. *
  306. * @return array
  307. */
  308. public static function get_extra_fields_by_handler($handler)
  309. {
  310. $types= array();
  311. $types[self::FIELD_TYPE_TEXT] = get_lang('FieldTypeText');
  312. $types[self::FIELD_TYPE_TEXTAREA] = get_lang('FieldTypeTextarea');
  313. $types[self::FIELD_TYPE_RADIO] = get_lang('FieldTypeRadio');
  314. $types[self::FIELD_TYPE_SELECT] = get_lang('FieldTypeSelect');
  315. $types[self::FIELD_TYPE_SELECT_MULTIPLE] = get_lang('FieldTypeSelectMultiple');
  316. $types[self::FIELD_TYPE_DATE] = get_lang('FieldTypeDate');
  317. $types[self::FIELD_TYPE_DATETIME] = get_lang('FieldTypeDatetime');
  318. $types[self::FIELD_TYPE_DOUBLE_SELECT] = get_lang('FieldTypeDoubleSelect');
  319. $types[self::FIELD_TYPE_DIVIDER] = get_lang('FieldTypeDivider');
  320. $types[self::FIELD_TYPE_TAG] = get_lang('FieldTypeTag');
  321. $types[self::FIELD_TYPE_TIMEZONE] = get_lang('FieldTypeTimezone');
  322. $types[self::FIELD_TYPE_SOCIAL_PROFILE] = get_lang('FieldTypeSocialProfile');
  323. $types[self::FIELD_TYPE_MOBILE_PHONE_NUMBER] = get_lang('FieldTypeMobilePhoneNumber');
  324. $types[self::FIELD_TYPE_CHECKBOX] = get_lang('FieldTypeCheckbox');
  325. $types[self::FIELD_TYPE_INTEGER] = get_lang('FieldTypeInteger');
  326. $types[self::FIELD_TYPE_FILE_IMAGE] = get_lang('FieldTypeFileImage');
  327. $types[self::FIELD_TYPE_FLOAT] = get_lang('FieldTypeFloat');
  328. $types[self::FIELD_TYPE_FILE] = get_lang('FieldTypeFile');
  329. $types[self::FIELD_TYPE_VIDEO_URL] = get_lang('FieldTypeVideoUrl');
  330. $types[self::FIELD_TYPE_LETTERS_ONLY] = get_lang('FieldTypeOnlyLetters');
  331. $types[self::FIELD_TYPE_ALPHANUMERIC] = get_lang('FieldTypeAlphanumeric');
  332. $types[self::FIELD_TYPE_LETTERS_SPACE] = get_lang(
  333. 'FieldTypeLettersSpaces'
  334. );
  335. $types[self::FIELD_TYPE_ALPHANUMERIC_SPACE] = get_lang(
  336. 'FieldTypeAlphanumericSpaces'
  337. );
  338. switch ($handler) {
  339. case 'course':
  340. case 'session':
  341. case 'user':
  342. break;
  343. }
  344. return $types;
  345. }
  346. /**
  347. * Add elements to a form
  348. *
  349. * @param FormValidator $form
  350. * @param int $itemId
  351. * @param array $exclude variables of extra field to exclude
  352. * @return array|bool
  353. */
  354. public function addElements($form, $itemId = 0, $exclude = [])
  355. {
  356. if (empty($form)) {
  357. return false;
  358. }
  359. $itemId = intval($itemId);
  360. $form->addHidden('item_id', $itemId);
  361. $extraData = false;
  362. if (!empty($itemId)) {
  363. $extraData = self::get_handler_extra_data($itemId);
  364. if ($form) {
  365. $form->setDefaults($extraData);
  366. }
  367. }
  368. $extraFields = $this->get_all(null, 'option_order');
  369. $extra = $this->set_extra_fields_in_form(
  370. $form,
  371. $extraData,
  372. false,
  373. $extraFields,
  374. $itemId,
  375. $exclude
  376. );
  377. return $extra;
  378. }
  379. /**
  380. * @param int $itemId (session_id, question_id, course id)
  381. *
  382. * @return array
  383. */
  384. public function get_handler_extra_data($itemId)
  385. {
  386. if (empty($itemId)) {
  387. return array();
  388. }
  389. $extra_data = array();
  390. $fields = self::get_all();
  391. $field_values = new ExtraFieldValue($this->type);
  392. if (!empty($fields) > 0) {
  393. foreach ($fields as $field) {
  394. $field_value = $field_values->get_values_by_handler_and_field_id(
  395. $itemId, $field['id']
  396. );
  397. if ($field['field_type'] == ExtraField::FIELD_TYPE_TAG) {
  398. $tags = UserManager::get_user_tags_to_string($itemId, $field['id'], false);
  399. $extra_data['extra_'.$field['variable']] = $tags;
  400. continue;
  401. }
  402. if ($field_value) {
  403. $field_value = $field_value['value'];
  404. switch ($field['field_type']) {
  405. case ExtraField::FIELD_TYPE_TAG:
  406. $tags = UserManager::get_user_tags_to_string($itemId, $field['id'], false);
  407. $extra_data['extra_'.$field['variable']] = $tags;
  408. break;
  409. case ExtraField::FIELD_TYPE_DOUBLE_SELECT:
  410. $selected_options = explode(
  411. '::',
  412. $field_value
  413. );
  414. $firstOption = isset($selected_options[0]) ? $selected_options[0] : '';
  415. $secondOption = isset($selected_options[1]) ? $selected_options[1] : '';
  416. $extra_data['extra_'.$field['variable']]['extra_'.$field['variable']] = $firstOption;
  417. $extra_data['extra_'.$field['variable']]['extra_'.$field['variable'].'_second'] = $secondOption;
  418. break;
  419. case ExtraField::FIELD_TYPE_SELECT_MULTIPLE:
  420. $field_value = explode(';', $field_value);
  421. $extra_data['extra_'.$field['variable']] = $field_value;
  422. break;
  423. case ExtraField::FIELD_TYPE_RADIO:
  424. $extra_data['extra_'.$field['variable']]['extra_'.$field['variable']] = $field_value;
  425. break;
  426. default:
  427. $extra_data['extra_'.$field['variable']] = $field_value;
  428. break;
  429. }
  430. } else {
  431. // Set default values
  432. if (isset($field['field_default_value']) && !empty($field['field_default_value'])) {
  433. $extra_data['extra_'.$field['variable']] = $field['field_default_value'];
  434. }
  435. }
  436. }
  437. }
  438. return $extra_data;
  439. }
  440. /**
  441. * @param string $field_type
  442. *
  443. * @return array
  444. */
  445. public function get_all_extra_field_by_type($field_type)
  446. {
  447. // all the information of the field
  448. $sql = "SELECT * FROM {$this->table}
  449. WHERE
  450. field_type = '".Database::escape_string($field_type)."' AND
  451. extra_field_type = $this->extraFieldType
  452. ";
  453. $result = Database::query($sql);
  454. $return = array();
  455. while ($row = Database::fetch_array($result)) {
  456. $return[] = $row['id'];
  457. }
  458. return $return;
  459. }
  460. /**
  461. * @return array
  462. */
  463. public function get_field_types()
  464. {
  465. return self::get_extra_fields_by_handler($this->type);
  466. }
  467. /**
  468. * @param int $id
  469. *
  470. * @return null
  471. */
  472. public function get_field_type_by_id($id)
  473. {
  474. $types = self::get_field_types();
  475. if (isset($types[$id])) {
  476. return $types[$id];
  477. }
  478. return null;
  479. }
  480. /**
  481. * Converts a string like this:
  482. * France:Paris;Bretagne;Marseilles;Lyon|Belgique:Bruxelles;Namur;Liège;Bruges|Peru:Lima;Piura;
  483. * into
  484. * array(
  485. * 'France' =>
  486. * array('Paris', 'Bregtane', 'Marseilles'),
  487. * 'Belgique' =>
  488. * array('Namur', 'Liège')
  489. * ), etc
  490. * @param string $string
  491. *
  492. * @return array
  493. */
  494. public static function extra_field_double_select_convert_string_to_array($string)
  495. {
  496. $options = explode('|', $string);
  497. $options_parsed = array();
  498. $id = 0;
  499. if (!empty($options)) {
  500. foreach ($options as $sub_options) {
  501. $options = explode(':', $sub_options);
  502. $sub_sub_options = explode(';', $options[1]);
  503. $options_parsed[$id] = array(
  504. 'label' => $options[0],
  505. 'options' => $sub_sub_options,
  506. );
  507. $id++;
  508. }
  509. }
  510. return $options_parsed;
  511. }
  512. /**
  513. * @param array $options
  514. *
  515. * @return array
  516. */
  517. public static function extra_field_double_select_convert_array_to_ordered_array($options)
  518. {
  519. $options_parsed = array();
  520. if (!empty($options)) {
  521. foreach ($options as $option) {
  522. if ($option['option_value'] == 0) {
  523. $options_parsed[$option['id']][] = $option;
  524. } else {
  525. $options_parsed[$option['option_value']][] = $option;
  526. }
  527. }
  528. }
  529. return $options_parsed;
  530. }
  531. /**
  532. * @param array $options the result of the get_field_options_by_field() array
  533. *
  534. * @return string
  535. */
  536. public static function extra_field_double_select_convert_array_to_string($options)
  537. {
  538. $string = null;
  539. $options_parsed = self::extra_field_double_select_convert_array_to_ordered_array($options);
  540. if (!empty($options_parsed)) {
  541. foreach ($options_parsed as $option) {
  542. foreach ($option as $key => $item) {
  543. $string .= $item['display_text'];
  544. if ($key == 0) {
  545. $string .= ':';
  546. } else {
  547. if (isset($option[$key + 1])) {
  548. $string .= ';';
  549. }
  550. }
  551. }
  552. $string .= '|';
  553. }
  554. }
  555. if (!empty($string)) {
  556. $string = substr($string, 0, strlen($string) - 1);
  557. }
  558. return $string;
  559. }
  560. /**
  561. * @param array $params
  562. *
  563. * @return array
  564. */
  565. public function clean_parameters($params)
  566. {
  567. if (!isset($params['variable']) || empty($params['variable'])) {
  568. $params['variable'] = $params['display_text'];
  569. }
  570. $params['variable'] = trim(strtolower(str_replace(" ", "_", $params['variable'])));
  571. if (!isset($params['field_order'])) {
  572. $max_order = self::get_max_field_order();
  573. $params['field_order'] = $max_order;
  574. }
  575. return $params;
  576. }
  577. /**
  578. * @param array $params
  579. * @param bool $show_query
  580. *
  581. * @return bool
  582. */
  583. public function save($params, $show_query = false)
  584. {
  585. $fieldInfo = self::get_handler_field_info_by_field_variable($params['variable']);
  586. $params = self::clean_parameters($params);
  587. $params['extra_field_type'] = $this->extraFieldType;
  588. if ($fieldInfo) {
  589. return $fieldInfo['id'];
  590. } else {
  591. $id = parent::save($params, $show_query);
  592. if ($id) {
  593. $session_field_option = new ExtraFieldOption($this->type);
  594. $params['field_id'] = $id;
  595. $session_field_option->save($params);
  596. }
  597. return $id;
  598. }
  599. }
  600. /**
  601. * @param array $params
  602. *
  603. * @return bool|void
  604. */
  605. public function update($params)
  606. {
  607. $params = self::clean_parameters($params);
  608. if (isset($params['id'])) {
  609. $field_option = new ExtraFieldOption($this->type);
  610. $params['field_id'] = $params['id'];
  611. $field_option->save($params);
  612. }
  613. parent::update($params);
  614. }
  615. /**
  616. * @param $id
  617. *
  618. * @return bool|void
  619. */
  620. public function delete($id)
  621. {
  622. $field_option = new ExtraFieldOption($this->type);
  623. $field_option->delete_all_options_by_field_id($id);
  624. $session_field_values = new ExtraFieldValue($this->type);
  625. $session_field_values->delete_all_values_by_field_id($id);
  626. parent::delete($id);
  627. }
  628. /**
  629. * @param FormValidator $form
  630. * @param array $extraData
  631. * @param bool $admin_permissions
  632. * @param int $user_id
  633. * @param array $extra
  634. * @param int $itemId
  635. * @param array $exclude variables of extra field to exclude
  636. * @return array
  637. */
  638. public function set_extra_fields_in_form(
  639. $form,
  640. $extraData,
  641. $admin_permissions = false,
  642. $extra = array(),
  643. $itemId = null,
  644. $exclude = []
  645. ) {
  646. $type = $this->type;
  647. $jquery_ready_content = null;
  648. if (!empty($extra)) {
  649. foreach ($extra as $field_details) {
  650. // Getting default value id if is set
  651. $defaultValueId = null;
  652. if (isset($field_details['options']) && !empty($field_details['options'])) {
  653. $valueToFind = null;
  654. if (isset($field_details['field_default_value'])) {
  655. $valueToFind = $field_details['field_default_value'];
  656. }
  657. // If a value is found we override the default value
  658. if (isset($extraData['extra_'.$field_details['variable']])) {
  659. $valueToFind = $extraData['extra_'.$field_details['variable']];
  660. }
  661. foreach ($field_details['options'] as $option) {
  662. if ($option['option_value'] == $valueToFind) {
  663. $defaultValueId = $option['id'];
  664. }
  665. }
  666. }
  667. if (!$admin_permissions) {
  668. if ($field_details['visible'] == 0) {
  669. continue;
  670. }
  671. if (in_array($field_details['variable'], $exclude)) {
  672. continue;
  673. }
  674. }
  675. switch ($field_details['field_type']) {
  676. case ExtraField::FIELD_TYPE_TEXT:
  677. $form->addElement(
  678. 'text',
  679. 'extra_'.$field_details['variable'],
  680. $field_details['display_text'],
  681. array()
  682. );
  683. $form->applyFilter('extra_'.$field_details['variable'], 'stripslashes');
  684. $form->applyFilter('extra_'.$field_details['variable'], 'trim');
  685. if (!$admin_permissions) {
  686. if ($field_details['visible'] == 0) {
  687. $form->freeze(
  688. 'extra_'.$field_details['variable']
  689. );
  690. }
  691. }
  692. break;
  693. case ExtraField::FIELD_TYPE_TEXTAREA:
  694. $form->addHtmlEditor(
  695. 'extra_'.$field_details['variable'],
  696. $field_details['display_text'],
  697. false,
  698. false,
  699. array('ToolbarSet' => 'Profile', 'Width' => '100%', 'Height' => '130')
  700. );
  701. $form->applyFilter('extra_'.$field_details['variable'], 'stripslashes');
  702. $form->applyFilter('extra_'.$field_details['variable'], 'trim');
  703. if (!$admin_permissions) {
  704. if ($field_details['visible'] == 0) {
  705. $form->freeze(
  706. 'extra_'.$field_details['variable']
  707. );
  708. }
  709. }
  710. break;
  711. case ExtraField::FIELD_TYPE_RADIO:
  712. $group = array();
  713. if (isset($field_details['options']) && !empty($field_details['options'])) {
  714. foreach ($field_details['options'] as $option_details) {
  715. $options[$option_details['option_value']] = $option_details['display_text'];
  716. $group[] = $form->createElement(
  717. 'radio',
  718. 'extra_'.$field_details['variable'],
  719. $option_details['option_value'],
  720. $option_details['display_text'].'<br />',
  721. $option_details['option_value']
  722. );
  723. }
  724. }
  725. $form->addGroup(
  726. $group,
  727. 'extra_'.$field_details['variable'],
  728. $field_details['display_text'],
  729. ''
  730. );
  731. if (!$admin_permissions) {
  732. if ($field_details['visible'] == 0) {
  733. $form->freeze(
  734. 'extra_'.$field_details['variable']
  735. );
  736. }
  737. }
  738. break;
  739. case ExtraField::FIELD_TYPE_CHECKBOX:
  740. $group = array();
  741. if (isset($field_details['options']) && !empty($field_details['options'])) {
  742. foreach ($field_details['options'] as $option_details) {
  743. $options[$option_details['option_value']] = $option_details['display_text'];
  744. $group[] = $form->createElement(
  745. 'checkbox',
  746. 'extra_'.$field_details['variable'],
  747. $option_details['option_value'],
  748. $option_details['display_text'].'<br />',
  749. $option_details['option_value']
  750. );
  751. }
  752. } else {
  753. $fieldVariable = "extra_{$field_details['variable']}";
  754. $checkboxAttributes = array();
  755. if (is_array($extraData) && array_key_exists($fieldVariable, $extraData)) {
  756. if (!empty($extraData[$fieldVariable])) {
  757. $checkboxAttributes['checked'] = 1;
  758. }
  759. }
  760. // We assume that is a switch on/off with 1 and 0 as values
  761. $group[] = $form->createElement(
  762. 'checkbox',
  763. 'extra_'.$field_details['variable'],
  764. null,
  765. //$field_details['display_text'].'<br />',
  766. get_lang('Yes'),
  767. $checkboxAttributes
  768. );
  769. }
  770. $form->addGroup(
  771. $group,
  772. 'extra_'.$field_details['variable'],
  773. $field_details['display_text'],
  774. ''
  775. );
  776. if (!$admin_permissions) {
  777. if ($field_details['visible'] == 0) {
  778. $form->freeze(
  779. 'extra_'.$field_details['variable']
  780. );
  781. }
  782. }
  783. break;
  784. case ExtraField::FIELD_TYPE_SELECT:
  785. $get_lang_variables = false;
  786. if (in_array(
  787. $field_details['variable'],
  788. array('mail_notify_message', 'mail_notify_invitation', 'mail_notify_group_message')
  789. )
  790. ) {
  791. $get_lang_variables = true;
  792. }
  793. // Get extra field workflow
  794. $userInfo = api_get_user_info();
  795. $addOptions = array();
  796. $optionsExists = false;
  797. global $app;
  798. // Check if exist $app['orm.em'] object
  799. if (isset($app['orm.em']) && is_object($app['orm.em'])) {
  800. $optionsExists = $app['orm.em']
  801. ->getRepository('ChamiloLMS\Entity\ExtraFieldOptionRelFieldOption')
  802. ->findOneBy(array('fieldId' => $field_details['id']));
  803. }
  804. if ($optionsExists) {
  805. if (isset($userInfo['status']) && !empty($userInfo['status'])) {
  806. $fieldWorkFlow = $app['orm.em']->getRepository('ChamiloLMS\Entity\ExtraFieldOptionRelFieldOption')
  807. ->findBy(
  808. array(
  809. 'fieldId' => $field_details['id'],
  810. 'relatedFieldOptionId' => $defaultValueId,
  811. 'roleId' => $userInfo['status']
  812. )
  813. );
  814. foreach ($fieldWorkFlow as $item) {
  815. $addOptions[] = $item->getFieldOptionId();
  816. }
  817. }
  818. }
  819. $options = array();
  820. if (empty($defaultValueId)) {
  821. $options[''] = get_lang('SelectAnOption');
  822. }
  823. $optionList = array();
  824. if (!empty($field_details['options'])) {
  825. foreach ($field_details['options'] as $option_details) {
  826. $optionList[$option_details['id']] = $option_details;
  827. if ($get_lang_variables) {
  828. $options[$option_details['option_value']] = get_lang($option_details['display_text']);
  829. } else {
  830. if ($optionsExists) {
  831. // Adding always the default value
  832. if ($option_details['id'] == $defaultValueId) {
  833. $options[$option_details['option_value']] = $option_details['display_text'];
  834. } else {
  835. if (isset($addOptions) && !empty($addOptions)) {
  836. // Parsing filters
  837. if (in_array($option_details['id'], $addOptions)) {
  838. $options[$option_details['option_value']] = $option_details['display_text'];
  839. }
  840. }
  841. }
  842. } else {
  843. // Normal behaviour
  844. $options[$option_details['option_value']] = $option_details['display_text'];
  845. }
  846. }
  847. }
  848. if (isset($optionList[$defaultValueId])) {
  849. if (isset($optionList[$defaultValueId]['option_value']) &&
  850. $optionList[$defaultValueId]['option_value'] == 'aprobada'
  851. ) {
  852. // @todo function don't exists api_is_question_manager
  853. /*if (api_is_question_manager() == false) {
  854. $form->freeze();
  855. }*/
  856. }
  857. }
  858. // Setting priority message
  859. if (isset($optionList[$defaultValueId]) &&
  860. isset($optionList[$defaultValueId]['priority'])
  861. ) {
  862. if (!empty($optionList[$defaultValueId]['priority'])) {
  863. $priorityId = $optionList[$defaultValueId]['priority'];
  864. $option = new ExtraFieldOption($this->type);
  865. $messageType = $option->getPriorityMessageType($priorityId);
  866. $form->addElement(
  867. 'label',
  868. null,
  869. Display::return_message(
  870. $optionList[$defaultValueId]['priority_message'],
  871. $messageType
  872. )
  873. );
  874. }
  875. }
  876. }
  877. if ($get_lang_variables) {
  878. $field_details['display_text'] = get_lang($field_details['display_text']);
  879. }
  880. // chzn-select doesn't work for sessions??
  881. $form->addElement(
  882. 'select',
  883. 'extra_' . $field_details['variable'],
  884. $field_details['display_text'],
  885. $options,
  886. array('id' => 'extra_'.$field_details['variable'])
  887. );
  888. /* Enable this when field_loggeable is introduced as a table field (2.0)
  889. if ($optionsExists && $field_details['field_loggeable'] && !empty($defaultValueId)) {
  890. $form->addElement(
  891. 'textarea',
  892. 'extra_' . $field_details['variable'] . '_comment',
  893. $field_details['display_text'] . ' ' . get_lang('Comment')
  894. );
  895. $extraFieldValue = new ExtraFieldValue($this->type);
  896. $repo = $app['orm.em']->getRepository($extraFieldValue->entityName);
  897. $repoLog = $app['orm.em']->getRepository('Gedmo\Loggable\Entity\LogEntry');
  898. $newEntity = $repo->findOneBy(
  899. array(
  900. $this->handlerEntityId => $itemId,
  901. 'fieldId' => $field_details['id']
  902. )
  903. );
  904. // @todo move this in a function inside the class
  905. if ($newEntity) {
  906. $logs = $repoLog->getLogEntries($newEntity);
  907. if (!empty($logs)) {
  908. $html = '<b>' . get_lang('LatestChanges') . '</b><br /><br />';
  909. $table = new HTML_Table(array('class' => 'data_table'));
  910. $table->setHeaderContents(0, 0, get_lang('Value'));
  911. $table->setHeaderContents(0, 1, get_lang('Comment'));
  912. $table->setHeaderContents(0, 2, get_lang('ModifyDate'));
  913. $table->setHeaderContents(0, 3, get_lang('Username'));
  914. $row = 1;
  915. foreach ($logs as $log) {
  916. $column = 0;
  917. $data = $log->getData();
  918. $fieldValue = isset($data['fieldValue']) ? $data['fieldValue'] : null;
  919. $comment = isset($data['comment']) ? $data['comment'] : null;
  920. $table->setCellContents($row, $column, $fieldValue);
  921. $column++;
  922. $table->setCellContents($row, $column, $comment);
  923. $column++;
  924. $table->setCellContents($row, $column, api_get_local_time($log->getLoggedAt()->format('Y-m-d H:i:s')));
  925. $column++;
  926. $table->setCellContents($row, $column, $log->getUsername());
  927. $row++;
  928. }
  929. $form->addElement('label', null, $html.$table->toHtml());
  930. }
  931. }
  932. }
  933. */
  934. if (!$admin_permissions) {
  935. if ($field_details['visible'] == 0) {
  936. $form->freeze('extra_' . $field_details['variable']);
  937. }
  938. }
  939. break;
  940. case ExtraField::FIELD_TYPE_SELECT_MULTIPLE:
  941. $options = array();
  942. foreach ($field_details['options'] as $option_id => $option_details) {
  943. $options[$option_details['option_value']] = $option_details['display_text'];
  944. }
  945. $form->addElement(
  946. 'select',
  947. 'extra_'.$field_details['variable'],
  948. $field_details['display_text'],
  949. $options,
  950. array('multiple' => 'multiple')
  951. );
  952. if (!$admin_permissions) {
  953. if ($field_details['visible'] == 0) {
  954. $form->freeze('extra_'.$field_details['variable']);
  955. }
  956. }
  957. break;
  958. case ExtraField::FIELD_TYPE_DATE:
  959. $form->addDatePicker('extra_'.$field_details['variable'], $field_details['display_text']);
  960. if (!$admin_permissions) {
  961. if ($field_details['visible'] == 0) {
  962. $form->freeze('extra_'.$field_details['variable']);
  963. }
  964. }
  965. $form->applyFilter('theme', 'trim');
  966. break;
  967. case ExtraField::FIELD_TYPE_DATETIME:
  968. $form->addDateTimePicker(
  969. 'extra_'.$field_details['variable'],
  970. $field_details['display_text']
  971. );
  972. $defaults['extra_'.$field_details['variable']] = api_get_local_time();
  973. if (!isset($form->_defaultValues['extra_'.$field_details['variable']])) {
  974. $form->setDefaults($defaults);
  975. }
  976. if (!$admin_permissions) {
  977. if ($field_details['visible'] == 0) {
  978. $form->freeze('extra_'.$field_details['variable']);
  979. }
  980. }
  981. $form->applyFilter('theme', 'trim');
  982. break;
  983. case ExtraField::FIELD_TYPE_DOUBLE_SELECT:
  984. $first_select_id = 'first_extra_'.$field_details['variable'];
  985. $url = api_get_path(WEB_AJAX_PATH).'extra_field.ajax.php?1=1';
  986. $jquery_ready_content .= '
  987. $("#'.$first_select_id.'").on("change", function() {
  988. var id = $(this).val();
  989. if (id) {
  990. $.ajax({
  991. url: "'.$url.'&a=get_second_select_options",
  992. dataType: "json",
  993. data: "type='.$type.'&field_id='.$field_details['id'].'&option_value_id="+id,
  994. success: function(data) {
  995. $("#second_extra_'.$field_details['variable'].'").empty();
  996. $.each(data, function(index, value) {
  997. $("#second_extra_'.$field_details['variable'].'").append($("<option/>", {
  998. value: index,
  999. text: value
  1000. }));
  1001. });
  1002. $("#second_extra_'.$field_details['variable'].'").selectpicker("refresh");
  1003. },
  1004. });
  1005. } else {
  1006. $("#second_extra_'.$field_details['variable'].'").empty();
  1007. }
  1008. });';
  1009. $first_id = null;
  1010. $second_id = null;
  1011. if (!empty($extraData)) {
  1012. $first_id = $extraData['extra_'.$field_details['variable']]['extra_'.$field_details['variable']];
  1013. $second_id = $extraData['extra_'.$field_details['variable']]['extra_'.$field_details['variable'].'_second'];
  1014. }
  1015. $options = ExtraField::extra_field_double_select_convert_array_to_ordered_array(
  1016. $field_details['options']
  1017. );
  1018. $values = array('' => get_lang('Select'));
  1019. $second_values = array();
  1020. if (!empty($options)) {
  1021. foreach ($options as $option) {
  1022. foreach ($option as $sub_option) {
  1023. if ($sub_option['option_value'] == '0') {
  1024. $values[$sub_option['id']] = $sub_option['display_text'];
  1025. } else {
  1026. if ($first_id === $sub_option['option_value']) {
  1027. $second_values[$sub_option['id']] = $sub_option['display_text'];
  1028. }
  1029. }
  1030. }
  1031. }
  1032. }
  1033. $group = array();
  1034. $group[] = $form->createElement(
  1035. 'select',
  1036. 'extra_'.$field_details['variable'],
  1037. null,
  1038. $values,
  1039. array('id' => $first_select_id)
  1040. );
  1041. $group[] = $form->createElement(
  1042. 'select',
  1043. 'extra_'.$field_details['variable'].'_second',
  1044. null,
  1045. $second_values,
  1046. array('id' => 'second_extra_'.$field_details['variable'])
  1047. );
  1048. $form->addGroup(
  1049. $group,
  1050. 'extra_'.$field_details['variable'],
  1051. $field_details['display_text'],
  1052. '&nbsp;'
  1053. );
  1054. if (!$admin_permissions) {
  1055. if ($field_details['visible'] == 0) {
  1056. $form->freeze('extra_'.$field_details['variable']);
  1057. }
  1058. }
  1059. break;
  1060. case ExtraField::FIELD_TYPE_DIVIDER:
  1061. $form->addElement(
  1062. 'static',
  1063. $field_details['variable'],
  1064. '<br /><strong>'.$field_details['display_text'].'</strong>'
  1065. );
  1066. break;
  1067. case ExtraField::FIELD_TYPE_TAG:
  1068. $variable = $field_details['variable'];
  1069. $field_id = $field_details['id'];
  1070. //Added for correctly translate the extra_field
  1071. $get_lang_variables = false;
  1072. if (in_array($variable, ['tags'])) {
  1073. $get_lang_variables = true;
  1074. }
  1075. if ($get_lang_variables) {
  1076. $field_details['display_text'] = get_lang($field_details['display_text']);
  1077. }
  1078. $tagsSelect = $form->addSelect(
  1079. "extra_{$field_details['variable']}",
  1080. $field_details['display_text']
  1081. );
  1082. $tagsSelect->setAttribute('class', null);
  1083. $tagsSelect->setAttribute('id', "extra_{$field_details['variable']}");
  1084. $tagsSelect->setMultiple(true);
  1085. if ($this->type == 'user') {
  1086. /* //the magic should be here
  1087. $user_tags = UserManager::get_user_tags($user_id, $field_details[0]);
  1088. $tag_list = '';
  1089. if (is_array($user_tags) && count($user_tags) > 0) {
  1090. foreach ($user_tags as $tag) {
  1091. $tag_list .= '<option value="'.$tag['tag'].'" class="selected">'.$tag['tag'].'</option>';
  1092. }
  1093. }
  1094. $multi_select = '<select id="extra_'.$field_details[1].'" name="extra_'.$field_details[1].'">
  1095. '.$tag_list.'
  1096. </select>';
  1097. $form->addElement('label', $field_details[3], $multi_select);
  1098. $url = api_get_path(WEB_AJAX_PATH).'user_manager.ajax.php';
  1099. $complete_text = get_lang('StartToType');
  1100. //if cache is set to true the jquery will be called 1 time
  1101. $jquery_ready_content = <<<EOF
  1102. $("#extra_$field_details[1]").fcbkcomplete({
  1103. json_url: "$url?a=search_tags&field_id=$field_details[0]",
  1104. cache: false,
  1105. filter_case: true,
  1106. filter_hide: true,
  1107. complete_text:"$complete_text",
  1108. firstselected: true,
  1109. //onremove: "testme",
  1110. //onselect: "testme",
  1111. filter_selected: true,
  1112. newel: true
  1113. });
  1114. EOF;
  1115. break;*/
  1116. // The magic should be here
  1117. $user_tags = UserManager::get_user_tags($itemId, $field_details['id']);
  1118. if (is_array($user_tags) && count($user_tags) > 0) {
  1119. foreach ($user_tags as $tag) {
  1120. $tagsSelect->addOption(
  1121. $tag['tag'],
  1122. $tag['tag'],
  1123. ['selected' => 'selected', 'class' => 'selected']
  1124. );
  1125. }
  1126. }
  1127. $url = api_get_path(WEB_AJAX_PATH).'user_manager.ajax.php';
  1128. } else {
  1129. $em = Database::getManager();
  1130. $fieldTags = $em
  1131. ->getRepository('ChamiloCoreBundle:ExtraFieldRelTag')
  1132. ->findBy([
  1133. 'fieldId' => $field_id,
  1134. 'itemId' => $itemId
  1135. ]);
  1136. foreach ($fieldTags as $fieldTag) {
  1137. $tag = $em->find('ChamiloCoreBundle:Tag', $fieldTag->getTagId());
  1138. if (empty($tag)) {
  1139. continue;
  1140. }
  1141. $tagsSelect->addOption(
  1142. $tag->getTag(),
  1143. $tag->getTag(),
  1144. ['selected' => 'selected', 'class' => 'selected']
  1145. );
  1146. }
  1147. $url = api_get_path(WEB_AJAX_PATH).'extra_field.ajax.php';
  1148. }
  1149. $complete_text = get_lang('StartToType');
  1150. //if cache is set to true the jquery will be called 1 time
  1151. $jquery_ready_content .= <<<EOF
  1152. $("#extra_$variable").fcbkcomplete({
  1153. json_url: "$url?a=search_tags&field_id=$field_id&type={$this->type}",
  1154. cache: false,
  1155. filter_case: true,
  1156. filter_hide: true,
  1157. complete_text:"$complete_text",
  1158. firstselected: false,
  1159. filter_selected: true,
  1160. newel: true
  1161. });
  1162. EOF;
  1163. break;
  1164. case ExtraField::FIELD_TYPE_TIMEZONE:
  1165. $form->addElement(
  1166. 'select',
  1167. 'extra_'.$field_details['variable'],
  1168. $field_details['display_text'],
  1169. api_get_timezones(),
  1170. ''
  1171. );
  1172. if ($field_details['visible'] == 0) {
  1173. $form->freeze(
  1174. 'extra_'.$field_details['variable']
  1175. );
  1176. }
  1177. break;
  1178. case ExtraField::FIELD_TYPE_SOCIAL_PROFILE:
  1179. // get the social network's favicon
  1180. $extra_data_variable = isset($extraData['extra_'.$field_details['variable']]) ? $extraData['extra_'.$field_details['variable']] : null;
  1181. $field_default_value = isset($field_details['field_default_value']) ? $field_details['field_default_value'] : null;
  1182. $icon_path = UserManager::get_favicon_from_url(
  1183. $extra_data_variable,
  1184. $field_default_value
  1185. );
  1186. // special hack for hi5
  1187. $leftpad = '1.7';
  1188. $top = '0.4';
  1189. $domain = parse_url($icon_path, PHP_URL_HOST);
  1190. if ($domain == 'www.hi5.com' or $domain == 'hi5.com') {
  1191. $leftpad = '3';
  1192. $top = '0';
  1193. }
  1194. // print the input field
  1195. $form->addElement(
  1196. 'text',
  1197. 'extra_'.$field_details['variable'],
  1198. $field_details['display_text'],
  1199. array(
  1200. 'size' => 60,
  1201. 'style' => 'background-image: url(\''.$icon_path.'\'); background-repeat: no-repeat; background-position: 0.4em '.$top.'em; padding-left: '.$leftpad.'em; '
  1202. )
  1203. );
  1204. $form->applyFilter('extra_'.$field_details['variable'], 'stripslashes');
  1205. $form->applyFilter('extra_'.$field_details['variable'], 'trim');
  1206. if ($field_details['visible'] == 0) {
  1207. $form->freeze('extra_'.$field_details['variable']);
  1208. }
  1209. break;
  1210. case ExtraField::FIELD_TYPE_MOBILE_PHONE_NUMBER:
  1211. $form->addElement(
  1212. 'text',
  1213. 'extra_'.$field_details[1],
  1214. $field_details[3]." (".get_lang('CountryDialCode').")",
  1215. array('size' => 40, 'placeholder' => '(xx)xxxxxxxxx')
  1216. );
  1217. $form->applyFilter('extra_'.$field_details[1], 'stripslashes');
  1218. $form->applyFilter('extra_'.$field_details[1], 'trim');
  1219. $form->applyFilter('extra_'.$field_details[1], 'mobile_phone_number_filter');
  1220. $form->addRule(
  1221. 'extra_'.$field_details[1],
  1222. get_lang('MobilePhoneNumberWrong'),
  1223. 'mobile_phone_number'
  1224. );
  1225. if ($field_details['visible'] == 0) {
  1226. $form->freeze('extra_'.$field_details['variable']);
  1227. }
  1228. break;
  1229. case ExtraField::FIELD_TYPE_INTEGER:
  1230. $form->addElement(
  1231. 'number',
  1232. 'extra_'.$field_details['variable'],
  1233. $field_details['display_text'],
  1234. array('class' => 'span1', 'step' => 1)
  1235. );
  1236. $form->applyFilter('extra_'.$field_details['variable'], 'stripslashes');
  1237. $form->applyFilter('extra_'.$field_details['variable'], 'trim');
  1238. $form->applyFilter('extra_'.$field_details['variable'], 'intval');
  1239. if (!$admin_permissions) {
  1240. if ($field_details['visible'] == 0) {
  1241. $form->freeze(
  1242. 'extra_'.$field_details['variable']
  1243. );
  1244. }
  1245. }
  1246. break;
  1247. case ExtraField::FIELD_TYPE_FILE_IMAGE:
  1248. $fieldVariable = "extra_{$field_details['variable']}";
  1249. $fieldTexts = array(
  1250. $field_details['display_text']
  1251. );
  1252. if (is_array($extraData) && array_key_exists($fieldVariable, $extraData)) {
  1253. if (file_exists(api_get_path(SYS_UPLOAD_PATH) . $extraData[$fieldVariable])) {
  1254. $fieldTexts[] = Display::img(
  1255. api_get_path(WEB_UPLOAD_PATH) . $extraData[$fieldVariable],
  1256. $field_details['display_text'],
  1257. array('width' => '300')
  1258. );
  1259. }
  1260. }
  1261. $form->addElement(
  1262. 'file',
  1263. $fieldVariable,
  1264. $fieldTexts,
  1265. array('accept' => 'image/*')
  1266. );
  1267. $form->applyFilter('extra_'.$field_details['variable'], 'stripslashes');
  1268. $form->applyFilter('extra_'.$field_details['variable'], 'trim');
  1269. $allowed_picture_types = array ('jpg', 'jpeg', 'png', 'gif');
  1270. $form->addRule(
  1271. 'extra_'.$field_details['variable'],
  1272. get_lang('OnlyImagesAllowed') . ' ('.implode(',', $allowed_picture_types).')',
  1273. 'filetype',
  1274. $allowed_picture_types
  1275. );
  1276. if (!$admin_permissions) {
  1277. if ($field_details['visible'] == 0) {
  1278. $form->freeze(
  1279. 'extra_'.$field_details['variable']
  1280. );
  1281. }
  1282. }
  1283. break;
  1284. case ExtraField::FIELD_TYPE_FLOAT:
  1285. $form->addElement(
  1286. 'number',
  1287. 'extra_'.$field_details['variable'],
  1288. $field_details['display_text'],
  1289. array('class' => 'span1', 'step' => '0.01')
  1290. );
  1291. $form->applyFilter('extra_'.$field_details['variable'], 'stripslashes');
  1292. $form->applyFilter('extra_'.$field_details['variable'], 'trim');
  1293. $form->applyFilter('extra_'.$field_details['variable'], 'floatval');
  1294. if (!$admin_permissions) {
  1295. if ($field_details['visible'] == 0) {
  1296. $form->freeze(
  1297. 'extra_'.$field_details['variable']
  1298. );
  1299. }
  1300. }
  1301. break;
  1302. case ExtraField::FIELD_TYPE_FILE:
  1303. $fieldVariable = "extra_{$field_details['variable']}";
  1304. $fieldTexts = array(
  1305. $field_details['display_text']
  1306. );
  1307. if (is_array($extraData) &&
  1308. array_key_exists($fieldVariable, $extraData)
  1309. ) {
  1310. if (file_exists(api_get_path(SYS_UPLOAD_PATH) . $extraData[$fieldVariable])) {
  1311. $fieldTexts[] = Display::url(
  1312. api_get_path(WEB_UPLOAD_PATH) . $extraData[$fieldVariable],
  1313. api_get_path(WEB_UPLOAD_PATH) . $extraData[$fieldVariable],
  1314. array(
  1315. 'title' => $field_details['display_text'],
  1316. 'target' => '_blank'
  1317. )
  1318. );
  1319. }
  1320. }
  1321. $form->addElement(
  1322. 'file',
  1323. $fieldVariable,
  1324. $fieldTexts,
  1325. array()
  1326. );
  1327. $form->applyFilter('extra_'.$field_details['variable'], 'stripslashes');
  1328. $form->applyFilter('extra_'.$field_details['variable'], 'trim');
  1329. if (!$admin_permissions) {
  1330. if ($field_details['visible'] == 0) {
  1331. $form->freeze(
  1332. 'extra_'.$field_details['variable']
  1333. );
  1334. }
  1335. }
  1336. break;
  1337. case ExtraField::FIELD_TYPE_VIDEO_URL:
  1338. //Added for correctly translate the extra_field
  1339. $get_lang_variables = false;
  1340. if (in_array($field_details['variable'], ['video_url'])) {
  1341. $get_lang_variables = true;
  1342. }
  1343. if ($get_lang_variables) {
  1344. $field_details['display_text'] = get_lang($field_details['display_text']);
  1345. }
  1346. $form->addUrl(
  1347. "extra_{$field_details['variable']}",
  1348. $field_details['display_text'],
  1349. false,
  1350. ['placeholder' => 'https://']
  1351. );
  1352. break;
  1353. case ExtraField::FIELD_TYPE_LETTERS_ONLY:
  1354. $form->addTextLettersOnly(
  1355. "extra_{$field_details['variable']}",
  1356. $field_details['display_text']
  1357. );
  1358. $form->applyFilter('extra_' . $field_details['variable'], 'stripslashes');
  1359. if (!$admin_permissions) {
  1360. if ($field_details['visible'] == 0) {
  1361. $form->freeze(
  1362. 'extra_' . $field_details['variable']
  1363. );
  1364. }
  1365. }
  1366. break;
  1367. case ExtraField::FIELD_TYPE_ALPHANUMERIC:
  1368. $form->addTextAlphanumeric(
  1369. "extra_{$field_details['variable']}",
  1370. $field_details['display_text']
  1371. );
  1372. $form->applyFilter(
  1373. 'extra_' . $field_details['variable'],
  1374. 'stripslashes'
  1375. );
  1376. if (!$admin_permissions) {
  1377. if ($field_details['visible'] == 0) {
  1378. $form->freeze(
  1379. 'extra_' . $field_details['variable']
  1380. );
  1381. }
  1382. }
  1383. break;
  1384. case ExtraField::FIELD_TYPE_LETTERS_SPACE:
  1385. $form->addTextLettersAndSpaces(
  1386. "extra_{$field_details['variable']}",
  1387. $field_details['display_text']
  1388. );
  1389. $form->applyFilter('extra_' . $field_details['variable'], 'stripslashes');
  1390. if (!$admin_permissions) {
  1391. if ($field_details['visible'] == 0) {
  1392. $form->freeze(
  1393. 'extra_' . $field_details['variable']
  1394. );
  1395. }
  1396. }
  1397. break;
  1398. case ExtraField::FIELD_TYPE_ALPHANUMERIC_SPACE:
  1399. $form->addTextAlphanumericAndSpaces(
  1400. "extra_{$field_details['variable']}",
  1401. $field_details['display_text']
  1402. );
  1403. $form->applyFilter(
  1404. 'extra_' . $field_details['variable'],
  1405. 'stripslashes'
  1406. );
  1407. if (!$admin_permissions) {
  1408. if ($field_details['visible'] == 0) {
  1409. $form->freeze(
  1410. 'extra_' . $field_details['variable']
  1411. );
  1412. }
  1413. }
  1414. break;
  1415. }
  1416. }
  1417. }
  1418. $return = array();
  1419. $return['jquery_ready_content'] = $jquery_ready_content;
  1420. return $return;
  1421. }
  1422. function setupBreadcrumb(&$breadcrumb, $action)
  1423. {
  1424. if ($action == 'add') {
  1425. $breadcrumb[] = array('url' => $this->pageUrl, 'name' => $this->pageName);
  1426. $breadcrumb[] = array('url' => '#', 'name' => get_lang('Add'));
  1427. } elseif ($action == 'edit') {
  1428. $breadcrumb[] = array('url' => $this->pageUrl, 'name' => $this->pageName);
  1429. $breadcrumb[] = array('url' => '#', 'name' => get_lang('Edit'));
  1430. } else {
  1431. $breadcrumb[] = array('url' => '#', 'name' => $this->pageName);
  1432. }
  1433. }
  1434. /**
  1435. * Displays the title + grid
  1436. */
  1437. public function display()
  1438. {
  1439. // action links
  1440. echo '<div class="actions">';
  1441. echo '<a href="../admin/index.php">'.Display::return_icon(
  1442. 'back.png',
  1443. get_lang('BackTo').' '.get_lang('PlatformAdmin'),
  1444. '',
  1445. ICON_SIZE_MEDIUM
  1446. ).'</a>';
  1447. echo '<a href="'.api_get_self().'?action=add&type='.$this->type.'">'.Display::return_icon(
  1448. 'add_user_fields.png',
  1449. get_lang('Add'),
  1450. '',
  1451. ICON_SIZE_MEDIUM
  1452. ).'</a>';
  1453. echo '</div>';
  1454. echo Display::grid_html($this->type.'_fields');
  1455. }
  1456. /**
  1457. * @return array
  1458. */
  1459. public function getJqgridColumnNames()
  1460. {
  1461. return array(
  1462. get_lang('Name'),
  1463. get_lang('FieldLabel'),
  1464. get_lang('Type'),
  1465. get_lang('FieldChangeability'),
  1466. get_lang('Visibility'),
  1467. get_lang('Filter'),
  1468. get_lang('FieldOrder'),
  1469. get_lang('Actions')
  1470. );
  1471. }
  1472. /**
  1473. * @return array
  1474. */
  1475. public function getJqgridColumnModel()
  1476. {
  1477. return array(
  1478. array(
  1479. 'name' => 'display_text',
  1480. 'index' => 'display_text',
  1481. 'width' => '180',
  1482. 'align' => 'left',
  1483. ),
  1484. array(
  1485. 'name' => 'variable',
  1486. 'index' => 'variable',
  1487. 'width' => '',
  1488. 'align' => 'left',
  1489. 'sortable' => 'true'
  1490. ),
  1491. array(
  1492. 'name' => 'field_type',
  1493. 'index' => 'field_type',
  1494. 'width' => '',
  1495. 'align' => 'left',
  1496. 'sortable' => 'true'
  1497. ),
  1498. array(
  1499. 'name' => 'changeable',
  1500. 'index' => 'changeable',
  1501. 'width' => '50',
  1502. 'align' => 'left',
  1503. 'sortable' => 'true'
  1504. ),
  1505. array(
  1506. 'name' => 'visible',
  1507. 'index' => 'visible',
  1508. 'width' => '40',
  1509. 'align' => 'left',
  1510. 'sortable' => 'true'
  1511. ),
  1512. array(
  1513. 'name' => 'filter',
  1514. 'index' => 'filter',
  1515. 'width' => '30',
  1516. 'align' => 'left',
  1517. 'sortable' => 'true'
  1518. ),
  1519. array(
  1520. 'name' => 'field_order',
  1521. 'index' => 'field_order',
  1522. 'width' => '40',
  1523. 'align' => 'left',
  1524. 'sortable' => 'true'
  1525. ),
  1526. array(
  1527. 'name' => 'actions',
  1528. 'index' => 'actions',
  1529. 'width' => '100',
  1530. 'align' => 'left',
  1531. 'formatter' => 'action_formatter',
  1532. 'sortable' => 'false'
  1533. )
  1534. );
  1535. }
  1536. /**
  1537. * @param string $url
  1538. * @param string $action
  1539. * @return FormValidator
  1540. */
  1541. public function return_form($url, $action)
  1542. {
  1543. $form = new FormValidator($this->type.'_field', 'post', $url);
  1544. $form->addElement('hidden', 'type', $this->type);
  1545. $id = isset($_GET['id']) ? intval($_GET['id']) : null;
  1546. $form->addElement('hidden', 'id', $id);
  1547. // Setting the form elements
  1548. $header = get_lang('Add');
  1549. $defaults = array();
  1550. if ($action == 'edit') {
  1551. $header = get_lang('Modify');
  1552. // Setting the defaults
  1553. $defaults = $this->get($id);
  1554. }
  1555. $form->addElement('header', $header);
  1556. $form->addElement('text', 'display_text', get_lang('Name'), array('class' => 'span5'));
  1557. // Field type
  1558. $types = self::get_field_types();
  1559. $form->addElement(
  1560. 'select',
  1561. 'field_type',
  1562. get_lang('FieldType'),
  1563. $types,
  1564. array('id' => 'field_type')
  1565. );
  1566. $form->addElement('label', get_lang('Example'), '<div id="example">-</div>');
  1567. $form->addElement('text', 'variable', get_lang('FieldLabel'), array('class' => 'span5'));
  1568. $form->addElement(
  1569. 'text',
  1570. 'field_options',
  1571. get_lang('FieldPossibleValues'),
  1572. array('id' => 'field_options', 'class' => 'span6')
  1573. );
  1574. $fieldWithOptions = array(
  1575. ExtraField::FIELD_TYPE_RADIO,
  1576. ExtraField::FIELD_TYPE_SELECT_MULTIPLE,
  1577. ExtraField::FIELD_TYPE_SELECT,
  1578. ExtraField::FIELD_TYPE_TAG,
  1579. ExtraField::FIELD_TYPE_DOUBLE_SELECT,
  1580. );
  1581. if ($action == 'edit') {
  1582. if (in_array($defaults['field_type'], $fieldWithOptions)) {
  1583. $url = Display::url(
  1584. get_lang('EditExtraFieldOptions'),
  1585. 'extra_field_options.php?type='.$this->type.'&field_id='.$id
  1586. );
  1587. $form->addElement('label', null, $url);
  1588. if ($defaults['field_type'] == ExtraField::FIELD_TYPE_SELECT) {
  1589. $urlWorkFlow = Display::url(
  1590. get_lang('EditExtraFieldWorkFlow'),
  1591. 'extra_field_workflow.php?type='.$this->type.'&field_id='.$id
  1592. );
  1593. $form->addElement('label', null, $urlWorkFlow);
  1594. }
  1595. $form->freeze('field_options');
  1596. }
  1597. }
  1598. $form->addElement(
  1599. 'text',
  1600. 'default_value',
  1601. get_lang('FieldDefaultValue'),
  1602. array('id' => 'default_value')
  1603. );
  1604. $group = array();
  1605. $group[] = $form->createElement('radio', 'visible', null, get_lang('Yes'), 1);
  1606. $group[] = $form->createElement('radio', 'visible', null, get_lang('No'), 0);
  1607. $form->addGroup($group, '', get_lang('Visible'), '', false);
  1608. $group = array();
  1609. $group[] = $form->createElement('radio', 'changeable', null, get_lang('Yes'), 1);
  1610. $group[] = $form->createElement('radio', 'changeable', null, get_lang('No'), 0);
  1611. $form->addGroup($group, '', get_lang('FieldChangeability'), '', false);
  1612. $group = array();
  1613. $group[] = $form->createElement('radio', 'filter', null, get_lang('Yes'), 1);
  1614. $group[] = $form->createElement('radio', 'filter', null, get_lang('No'), 0);
  1615. $form->addGroup($group, '', get_lang('FieldFilter'), '', false);
  1616. /* Enable this when field_loggeable is introduced as a table field (2.0)
  1617. $group = array();
  1618. $group[] = $form->createElement('radio', 'field_loggeable', null, get_lang('Yes'), 1);
  1619. $group[] = $form->createElement('radio', 'field_loggeable', null, get_lang('No'), 0);
  1620. $form->addGroup($group, '', get_lang('FieldLoggeable'), '', false);
  1621. */
  1622. $form->addElement('text', 'field_order', get_lang('FieldOrder'), array('class' => 'span1'));
  1623. if ($action == 'edit') {
  1624. $option = new ExtraFieldOption($this->type);
  1625. if ($defaults['field_type'] == ExtraField::FIELD_TYPE_DOUBLE_SELECT) {
  1626. $form->freeze('field_options');
  1627. }
  1628. $defaults['field_options'] = $option->get_field_options_by_field_to_string($id);
  1629. $form->addButtonUpdate(get_lang('Modify'));
  1630. } else {
  1631. $defaults['visible'] = 0;
  1632. $defaults['changeable'] = 0;
  1633. $defaults['filter'] = 0;
  1634. $form->addButtonCreate(get_lang('Add'));
  1635. }
  1636. /*if (!empty($defaults['created_at'])) {
  1637. $defaults['created_at'] = api_convert_and_format_date($defaults['created_at']);
  1638. }
  1639. if (!empty($defaults['updated_at'])) {
  1640. $defaults['updated_at'] = api_convert_and_format_date($defaults['updated_at']);
  1641. }*/
  1642. $form->setDefaults($defaults);
  1643. // Setting the rules
  1644. $form->addRule('display_text', get_lang('ThisFieldIsRequired'), 'required');
  1645. $form->addRule('field_type', get_lang('ThisFieldIsRequired'), 'required');
  1646. return $form;
  1647. }
  1648. /**
  1649. * @param $token
  1650. * @return string
  1651. */
  1652. public function getJqgridActionLinks($token)
  1653. {
  1654. //With this function we can add actions to the jgrid (edit, delete, etc)
  1655. return 'function action_formatter(cellvalue, options, rowObject) {
  1656. return \'<a href="?action=edit&type='.$this->type.'&id=\'+options.rowId+\'">'.Display::return_icon(
  1657. 'edit.png',
  1658. get_lang('Edit'),
  1659. '',
  1660. ICON_SIZE_SMALL
  1661. ).'</a>'.
  1662. '&nbsp;<a onclick="javascript:if(!confirm('."\'".addslashes(
  1663. api_htmlentities(get_lang("ConfirmYourChoice"), ENT_QUOTES)
  1664. )."\'".')) return false;" href="?sec_token='.$token.'&type='.$this->type.'&action=delete&id=\'+options.rowId+\'">'.Display::return_icon(
  1665. 'delete.png',
  1666. get_lang('Delete'),
  1667. '',
  1668. ICON_SIZE_SMALL
  1669. ).'</a>'.
  1670. '\';
  1671. }';
  1672. }
  1673. /**
  1674. * @param array $columns
  1675. * @param array $column_model
  1676. * @param array $extraFields
  1677. * @return array
  1678. */
  1679. public function getRules(&$columns, &$column_model, $extraFields = array(), $checkExtraFieldExistence = false)
  1680. {
  1681. $fields = $this->get_all(
  1682. array(
  1683. 'visible = ? AND filter = ?' => array(1, 1)
  1684. ),
  1685. 'display_text'
  1686. );
  1687. $extraFieldOption = new ExtraFieldOption($this->type);
  1688. $rules = array();
  1689. if (!empty($fields)) {
  1690. foreach ($fields as $field) {
  1691. $search_options = array();
  1692. $type = 'text';
  1693. if (in_array($field['field_type'], array(self::FIELD_TYPE_SELECT, self::FIELD_TYPE_DOUBLE_SELECT))) {
  1694. $type = 'select';
  1695. $search_options['sopt'] = array('eq', 'ne'); //equal not equal
  1696. } else {
  1697. $search_options['sopt'] = array('cn', 'nc'); //contains not contains
  1698. }
  1699. $search_options['searchhidden'] = 'true';
  1700. $search_options['defaultValue'] = isset($search_options['field_default_value']) ? $search_options['field_default_value'] : null;
  1701. if ($field['field_type'] == self::FIELD_TYPE_DOUBLE_SELECT) {
  1702. //Add 2 selects
  1703. $options = $extraFieldOption->get_field_options_by_field($field['id']);
  1704. $options = self::extra_field_double_select_convert_array_to_ordered_array($options);
  1705. $first_options = array();
  1706. if (!empty($options)) {
  1707. foreach ($options as $option) {
  1708. foreach ($option as $sub_option) {
  1709. if ($sub_option['option_value'] == 0) {
  1710. $first_options[] = $sub_option['field_id'].'#'.$sub_option['id'].':'.$sub_option['display_text'];
  1711. }
  1712. }
  1713. }
  1714. }
  1715. $search_options['value'] = implode(';', $first_options);
  1716. $search_options['dataInit'] = 'fill_second_select';
  1717. // First
  1718. $column_model[] = array(
  1719. 'name' => 'extra_'.$field['variable'],
  1720. 'index' => 'extra_'.$field['variable'],
  1721. 'width' => '100',
  1722. 'hidden' => 'true',
  1723. 'search' => 'true',
  1724. 'stype' => 'select',
  1725. 'searchoptions' => $search_options,
  1726. );
  1727. $columns[] = $field['display_text'].' (1)';
  1728. $rules[] = array(
  1729. 'field' => 'extra_'.$field['variable'],
  1730. 'op' => 'cn',
  1731. );
  1732. //Second
  1733. $search_options['value'] = $field['id'].':';
  1734. $search_options['dataInit'] = 'register_second_select';
  1735. $column_model[] = array(
  1736. 'name' => 'extra_'.$field['variable'].'_second',
  1737. 'index' => 'extra_'.$field['variable'].'_second',
  1738. 'width' => '100',
  1739. 'hidden' => 'true',
  1740. 'search' => 'true',
  1741. 'stype' => 'select',
  1742. 'searchoptions' => $search_options,
  1743. );
  1744. $columns[] = $field['display_text'].' (2)';
  1745. $rules[] = array('field' => 'extra_'.$field['variable'].'_second', 'op' => 'cn');
  1746. continue;
  1747. } else {
  1748. $search_options['value'] = $extraFieldOption->getFieldOptionsToString(
  1749. $field['id'],
  1750. false,
  1751. 'display_text'
  1752. );
  1753. }
  1754. $column_model[] = array(
  1755. 'name' => 'extra_'.$field['variable'],
  1756. 'index' => 'extra_'.$field['variable'],
  1757. 'width' => '100',
  1758. 'hidden' => 'true',
  1759. 'search' => 'true',
  1760. 'stype' => $type,
  1761. 'searchoptions' => $search_options
  1762. );
  1763. $columns[] = $field['display_text'];
  1764. $rules[] = array('field' => 'extra_'.$field['variable'], 'op' => 'cn');
  1765. }
  1766. }
  1767. return $rules;
  1768. }
  1769. /**
  1770. * @param array $options
  1771. * @return array
  1772. */
  1773. public function parseConditions($options)
  1774. {
  1775. $inject_extra_fields = null;
  1776. $extraFieldOption = new ExtraFieldOption($this->type);
  1777. $double_fields = array();
  1778. if (isset($options['extra'])) {
  1779. $extra_fields = $options['extra'];
  1780. if (!empty($extra_fields)) {
  1781. $counter = 1;
  1782. foreach ($extra_fields as &$extra) {
  1783. $extra_field_obj = new ExtraField($this->type);
  1784. $extra_field_info = $extra_field_obj->get($extra['id']);
  1785. $extra['extra_field_info'] = $extra_field_info;
  1786. if (isset($extra_field_info['field_type']) && in_array(
  1787. $extra_field_info['field_type'],
  1788. array(
  1789. ExtraField::FIELD_TYPE_SELECT,
  1790. ExtraField::FIELD_TYPE_SELECT,
  1791. ExtraField::FIELD_TYPE_DOUBLE_SELECT
  1792. )
  1793. )
  1794. ) {
  1795. $inject_extra_fields .= " fvo$counter.display_text as {$extra['field']}, ";
  1796. } else {
  1797. $inject_extra_fields .= " fv$counter.value as {$extra['field']}, ";
  1798. }
  1799. if (isset($extra_fields_info[$extra['id']])) {
  1800. $info = $extra_fields_info[$extra['id']];
  1801. } else {
  1802. $info = $this->get($extra['id']);
  1803. $extra_fields_info[$extra['id']] = $info;
  1804. }
  1805. if (isset($info['field_type']) && $info['field_type'] == ExtraField::FIELD_TYPE_DOUBLE_SELECT) {
  1806. $double_fields[$info['id']] = $info;
  1807. }
  1808. $counter++;
  1809. }
  1810. }
  1811. }
  1812. $options_by_double = array();
  1813. foreach ($double_fields as $double) {
  1814. $my_options = $extraFieldOption->get_field_options_by_field(
  1815. $double['id'],
  1816. true
  1817. );
  1818. $options_by_double['extra_'.$double['variable']] = $my_options;
  1819. }
  1820. $field_value_to_join = array();
  1821. //filter can be all/any = and/or
  1822. $inject_joins = null;
  1823. $inject_where = null;
  1824. $where = null;
  1825. if (!empty($options['where'])) {
  1826. if (!empty($options['extra'])) {
  1827. // Removing double 1=1
  1828. $options['where'] = str_replace(' 1 = 1 AND', '', $options['where']);
  1829. // Always OR
  1830. $counter = 1;
  1831. foreach ($extra_fields as $extra_info) {
  1832. $extra_field_info = $extra_info['extra_field_info'];
  1833. $inject_joins .= " INNER JOIN $this->table_field_values fv$counter
  1834. ON (s.".$this->primaryKey." = fv$counter.".$this->handler_id.") ";
  1835. // Add options
  1836. if (isset($extra_field_info['field_type']) && in_array(
  1837. $extra_field_info['field_type'],
  1838. array(
  1839. ExtraField::FIELD_TYPE_SELECT,
  1840. ExtraField::FIELD_TYPE_SELECT,
  1841. ExtraField::FIELD_TYPE_DOUBLE_SELECT
  1842. )
  1843. )
  1844. ) {
  1845. $options['where'] = str_replace(
  1846. $extra_info['field'],
  1847. 'fv'.$counter.'.field_id = '.$extra_info['id'].' AND fvo'.$counter.'.option_value',
  1848. $options['where']
  1849. );
  1850. $inject_joins .= " INNER JOIN $this->table_field_options fvo$counter ".
  1851. " ON (fv$counter.field_id = fvo$counter.field_id AND fv$counter.value = fvo$counter.option_value) ";
  1852. } else {
  1853. //text, textarea, etc
  1854. $options['where'] = str_replace(
  1855. $extra_info['field'],
  1856. 'fv'.$counter.'.field_id = '.$extra_info['id'].' AND fv'.$counter.'.value',
  1857. $options['where']
  1858. );
  1859. }
  1860. $field_value_to_join[] = " fv$counter.$this->handler_id ";
  1861. $counter++;
  1862. }
  1863. if (!empty($field_value_to_join)) {
  1864. //$inject_where .= " AND s.id = ".implode(' = ', $field_value_to_join);
  1865. }
  1866. }
  1867. $where .= ' AND '.$options['where'];
  1868. }
  1869. $order = null;
  1870. if (!empty($options['order'])) {
  1871. $order = " ORDER BY ".$options['order'];
  1872. }
  1873. $limit = null;
  1874. if (!empty($options['limit'])) {
  1875. $limit = " LIMIT ".$options['limit'];
  1876. }
  1877. return array(
  1878. 'order' => $order,
  1879. 'limit' => $limit,
  1880. 'where' => $where,
  1881. 'inject_where' => $inject_where,
  1882. 'inject_joins' => $inject_joins,
  1883. 'field_value_to_join' => $field_value_to_join,
  1884. 'inject_extra_fields' => $inject_extra_fields,
  1885. );
  1886. }
  1887. //@todo move this in the display_class or somewhere else
  1888. /**
  1889. * @param $col
  1890. * @param $oper
  1891. * @param $val
  1892. * @return string
  1893. */
  1894. public function get_where_clause($col, $oper, $val)
  1895. {
  1896. if (empty($col)) {
  1897. return '';
  1898. }
  1899. if ($oper == 'bw' || $oper == 'bn') {
  1900. $val .= '%';
  1901. }
  1902. if ($oper == 'ew' || $oper == 'en') {
  1903. $val = '%'.$val;
  1904. }
  1905. if ($oper == 'cn' || $oper == 'nc' || $oper == 'in' || $oper == 'ni') {
  1906. $val = '%'.$val.'%';
  1907. }
  1908. $val = \Database::escape_string($val);
  1909. return " $col {$this->ops[$oper]} '$val' ";
  1910. }
  1911. /**
  1912. * @param $filters
  1913. * @param string $stringToSearch
  1914. * @return array
  1915. */
  1916. public function getExtraFieldRules($filters, $stringToSearch = 'extra_')
  1917. {
  1918. $extra_fields = array();
  1919. // Getting double select if exists
  1920. $double_select = array();
  1921. foreach ($filters->rules as $rule) {
  1922. if (strpos($rule->field, '_second') === false) {
  1923. } else {
  1924. $my_field = str_replace('_second', '', $rule->field);
  1925. $double_select[$my_field] = $rule->data;
  1926. }
  1927. }
  1928. $condition_array = array();
  1929. foreach ($filters->rules as $rule) {
  1930. if (strpos($rule->field, $stringToSearch) === false) {
  1931. //normal fields
  1932. $field = $rule->field;
  1933. if (isset($rule->data) && $rule->data != -1) {
  1934. $condition_array[] = $this->get_where_clause($field, $rule->op, $rule->data);
  1935. }
  1936. } else {
  1937. // Extra fields
  1938. if (strpos($rule->field, '_second') === false) {
  1939. //No _second
  1940. $original_field = str_replace($stringToSearch, '', $rule->field);
  1941. $field_option = $this->get_handler_field_info_by_field_variable($original_field);
  1942. if ($field_option['field_type'] == ExtraField::FIELD_TYPE_DOUBLE_SELECT) {
  1943. if (isset($double_select[$rule->field])) {
  1944. $data = explode('#', $rule->data);
  1945. $rule->data = $data[1].'::'.$double_select[$rule->field];
  1946. } else {
  1947. // only was sent 1 select
  1948. $data = explode('#', $rule->data);
  1949. $rule->data = $data[1];
  1950. }
  1951. if (!isset($rule->data)) {
  1952. $condition_array[] = ' ('.$this->get_where_clause($rule->field, $rule->op, $rule->data).') ';
  1953. $extra_fields[] = array('field' => $rule->field, 'id' => $field_option['id']);
  1954. }
  1955. } else {
  1956. if (isset($rule->data)) {
  1957. if ($rule->data == -1) {
  1958. continue;
  1959. }
  1960. $condition_array[] = ' ('.$this->get_where_clause($rule->field, $rule->op, $rule->data).') ';
  1961. $extra_fields[] = array(
  1962. 'field' => $rule->field,
  1963. 'id' => $field_option['id'],
  1964. 'data' => $rule->data
  1965. );
  1966. }
  1967. }
  1968. } else {
  1969. $my_field = str_replace('_second', '', $rule->field);
  1970. $original_field = str_replace($stringToSearch, '', $my_field);
  1971. $field_option = $this->get_handler_field_info_by_field_variable($original_field);
  1972. $extra_fields[] = array(
  1973. 'field' => $rule->field,
  1974. 'id' => $field_option['id']
  1975. );
  1976. }
  1977. }
  1978. }
  1979. return array(
  1980. 'extra_fields' => $extra_fields,
  1981. 'condition_array' => $condition_array
  1982. );
  1983. }
  1984. /**
  1985. * Get the extra fields and their formatted values
  1986. * @param int|string $itemId The item ID (It could be a session_id, course_id or user_id)
  1987. * @return array The extra fields data
  1988. */
  1989. public function getDataAndFormattedValues($itemId)
  1990. {
  1991. $valuesData = array();
  1992. $fields = $this->get_all();
  1993. foreach ($fields as $field) {
  1994. if ($field['visible'] != '1') {
  1995. continue;
  1996. }
  1997. $fieldValue = new ExtraFieldValue($this->type);
  1998. $valueData = $fieldValue->get_values_by_handler_and_field_id($itemId, $field['id'], true);
  1999. if (!$valueData) {
  2000. continue;
  2001. }
  2002. $displayedValue = get_lang('None');
  2003. switch ($field['field_type']) {
  2004. case ExtraField::FIELD_TYPE_CHECKBOX:
  2005. if ($valueData !== false && $valueData['value'] == '1') {
  2006. $displayedValue = get_lang('Yes');
  2007. } else {
  2008. $displayedValue = get_lang('No');
  2009. }
  2010. break;
  2011. case ExtraField::FIELD_TYPE_DATE:
  2012. if ($valueData !== false && !empty($valueData['value'])) {
  2013. $displayedValue = api_format_date($valueData['value'], DATE_FORMAT_LONG_NO_DAY);
  2014. }
  2015. break;
  2016. case ExtraField::FIELD_TYPE_FILE_IMAGE:
  2017. if ($valueData === false || empty($valueData['value'])) {
  2018. break;
  2019. }
  2020. if (!file_exists(api_get_path(SYS_UPLOAD_PATH) . $valueData['value'])) {
  2021. break;
  2022. }
  2023. $image = Display::img(
  2024. api_get_path(WEB_UPLOAD_PATH) . $valueData['value'],
  2025. $field['display_text'],
  2026. array('width' => '300')
  2027. );
  2028. $displayedValue = Display::url(
  2029. $image,
  2030. api_get_path(WEB_UPLOAD_PATH) . $valueData['value'],
  2031. array('target' => '_blank')
  2032. );
  2033. break;
  2034. case ExtraField::FIELD_TYPE_FILE:
  2035. if ($valueData === false || empty($valueData['value'])) {
  2036. break;
  2037. }
  2038. if (!file_exists(api_get_path(SYS_UPLOAD_PATH) . $valueData['value'])) {
  2039. break;
  2040. }
  2041. $displayedValue = Display::url(
  2042. get_lang('Download'),
  2043. api_get_path(WEB_UPLOAD_PATH) . $valueData['value'],
  2044. array(
  2045. 'title' => $field['display_text'],
  2046. 'target' => '_blank'
  2047. )
  2048. );
  2049. break;
  2050. default:
  2051. $displayedValue = $valueData['value'];
  2052. break;
  2053. }
  2054. $valuesData[] = array(
  2055. 'text' => $field['display_text'],
  2056. 'value' => $displayedValue
  2057. );
  2058. }
  2059. return $valuesData;
  2060. }
  2061. }