PageRenderTime 45ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 1ms

/com_flexicontent_v2.x/plugins/relateditems/relateditems.php

http://flexicontent.googlecode.com/
PHP | 734 lines | 500 code | 121 blank | 113 comment | 107 complexity | 70aa7c4858320f45787090e17446af86 MD5 | raw file
Possible License(s): MIT, GPL-2.0, Apache-2.0
  1. <?php
  2. /**
  3. * @version 1.0 $Id: relateditems.php
  4. * @package Joomla
  5. * @subpackage FLEXIcontent
  6. * @subpackage plugin.relateditems
  7. * @copyright (C) 2011 ggppdk
  8. * @license GNU/GPL v2
  9. *
  10. * FLEXIcontent is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. */
  15. defined( '_JEXEC' ) or die( 'Restricted access' );
  16. jimport('joomla.event.plugin');
  17. class plgFlexicontent_fieldsRelateditems extends JPlugin
  18. {
  19. // ***********
  20. // CONSTRUCTOR
  21. // ***********
  22. function plgFlexicontent_fieldsRelateditems( &$subject, $params )
  23. {
  24. parent::__construct( $subject, $params );
  25. JPlugin::loadLanguage('plg_flexicontent_fields_relateditems', JPATH_ADMINISTRATOR);
  26. }
  27. // *******************************************
  28. // DISPLAY methods, item form & frontend views
  29. // *******************************************
  30. // Method to create field's HTML display for item form
  31. function onDisplayField(&$field, &$item)
  32. {
  33. // execute the code only if the field type match the plugin type
  34. if($field->field_type != 'relateditems') return;
  35. global $globalcats;
  36. $field->label = JText::_($field->label);
  37. // SCOPE PARAMETERS
  38. // categories scope parameters
  39. $method_cat = $field->parameters->get('method_cat', 1);
  40. $usesubcats = $field->parameters->get('usesubcats', 0 );
  41. $catids = $field->parameters->get('catids');
  42. if ( empty($catids) ) $catids = array();
  43. else if ( ! is_array($catids) ) $catids = !FLEXI_J16GE ? array($catids) : explode("|", $catids);
  44. // types scope parameters
  45. $method_types = $field->parameters->get('method_types', 1);
  46. $types = $field->parameters->get('types');
  47. if ( empty($types) ) $types = array();
  48. else if ( ! is_array($types) ) $types = !FLEXI_J16GE ? array($types) : explode("|", $types);
  49. // other limits of scope parameters
  50. $samelangonly = $field->parameters->get( 'samelangonly', 1 );
  51. $onlypublished = $field->parameters->get( 'onlypublished', 1 );
  52. // EDITING OPTIONS
  53. // Field height
  54. $size = $field->parameters->get( 'size', 12 ) ;
  55. $size = $size ? ' size="'.$size.'"' : '';
  56. $prepend_item_state = $field->parameters->get( 'prepend_item_state', 1 ) ;
  57. $maxtitlechars = $field->parameters->get( 'maxtitlechars', 40 ) ;
  58. $title_filter = $field->parameters->get( 'title_filter', 1 ) ;
  59. $required = $field->parameters->get( 'required', 0 ) ;
  60. $required = $required ? ' required' : '';
  61. // initialise property
  62. $default_values = '';
  63. if( $item->version == 0 && $default_values) {
  64. $field->value = explode(",", $default_values);
  65. } else if (!$field->value) {
  66. $field->value = array();
  67. } else {
  68. // Compatibility with old values, we no longer serialize all values to one, this way the field can be reversed !!!
  69. $field->value = ( $field_data = @unserialize($field->value[0]) ) ? $field_data : $field->value;
  70. }
  71. $fieldval = array();
  72. foreach($field->value as $i=>$val) {
  73. list ($itemid,$catid) = explode(":", $val);
  74. $fieldval[$itemid] = new stdClass();
  75. $fieldval[$itemid]->itemid = $itemid;
  76. $fieldval[$itemid]->catid = $catid;
  77. $fieldval[$itemid]->val = $val;
  78. }
  79. $db =& JFactory::getDBO();
  80. $user =& JFactory::getUser();
  81. if (FLEXI_ACCESS) {
  82. $usercats = FAccess::checkUserCats($user->gmid);
  83. $viewallcats = ($user->gid < 25) ? FAccess::checkComponentAccess('com_flexicontent', 'usercats', 'users', $user->gmid) : 1;
  84. $viewtree = ($user->gid < 25) ? FAccess::checkComponentAccess('com_flexicontent', 'cattree', 'users', $user->gmid) : 1;
  85. } else {
  86. $viewallcats = 1;
  87. $viewtree = 1;
  88. }
  89. if (!$viewtree) {
  90. $field->html = '<div class="fc_mini_note_box">'. JText::_('FLEXI_NO_ACCESS_LEVEL_TO_VIEW_CATEGORY_TREE') . '</div>';
  91. return;
  92. }
  93. //ob_start(); print_r($field->value); $field->html = ob_get_contents(); ob_end_clean();
  94. $where = "";
  95. // CATEGORY SCOPE
  96. $allowed_cats = $disallowed_cats = false;
  97. if ($usesubcats) {
  98. // Find descendants of the categories
  99. $subcats = array();
  100. foreach ($catids as $catid) {
  101. $subcats = array_merge($subcats, array_map('trim',explode(",",$globalcats[$catid]->descendants)) );
  102. }
  103. $catids = array_unique($subcats);
  104. }
  105. if ( $method_cat == 3 ) { // include method
  106. $allowed_cats = ($viewallcats) ? $catids : array_intersect($usercats, $catids);
  107. } else if ( $method_cat == 2 ) { // exclude method
  108. $disallowed_cats = ($viewallcats) ? $catids : array_diff($usercats, $catids);
  109. } else if (!$viewallcats) {
  110. $allowed_cats = $usercats;
  111. }
  112. if ( $allowed_cats && ( !count($allowed_cats) || empty($allowed_cats[0]) ) ) $allowed_cats = false;
  113. if ( $disallowed_cats && ( !count($disallowed_cats) || empty($disallowed_cats[0]) ) ) $disallowed_cats = false;
  114. if ( $allowed_cats ) {
  115. $where .= ($where=="") ? "" : " AND ";
  116. $where .= " rel.catid IN (".implode(',',$allowed_cats ).") ";
  117. }
  118. if ( $disallowed_cats ) {
  119. $where .= ($where=="") ? "" : " AND ";
  120. $where .= " rel.catid NOT IN (".implode(',',$disallowed_cats ).") ";
  121. }
  122. // TYPE SCOPE
  123. if ( $types && ( !count($types) || empty($types[0]) ) ) $types = false;
  124. if ($types) {
  125. if ($method_types == 2) { // exclude method
  126. $where .= ($where=="") ? "" : " AND ";
  127. $where .= ' ie.type_id NOT IN (' . implode(',', $types) . ')';
  128. } else if ($method_types == 3) { // include method
  129. $where .= ($where=="") ? "" : " AND ";
  130. $where .= ' ie.type_id IN (' . implode(',', $types) . ')';
  131. }
  132. } else if ($method_types == 2 || $method_types == 3) {
  133. $field->html = 'Content Type scope is set to include/exclude but no Types are selected in field configuration, please set to "ALL" or select types to include/exclude';
  134. return;
  135. }
  136. // OTHER SCOPE LIMITS
  137. if ($samelangonly) {
  138. if ($item->language!='*') { // for J2.5, but harmless for J1.5
  139. $where .= ($where=="") ? "" : " AND ";
  140. $where .= " (ie.language='{$item->language}' OR ie.language='*') ";
  141. }
  142. }
  143. if ($onlypublished) {
  144. $where .= ($where=="") ? "" : " AND ";
  145. $where .= " i.state IN (1, -5) ";
  146. }
  147. if ($where!="") $where = " WHERE " . $where;
  148. $order = $field->parameters->get( 'orderby_form', 'alpha' );
  149. $orderby = $this->_buildItemOrderBy($order);
  150. $query = "SELECT i.title, i.id, i.catid, i.state, GROUP_CONCAT(rel.catid SEPARATOR ',') as catlist, i.alias FROM #__content AS i "
  151. . (($samelangonly || $method_types>1) ? " LEFT JOIN #__flexicontent_items_ext AS ie on i.id=ie.item_id " : "")
  152. . ' LEFT JOIN #__flexicontent_cats_item_relations AS rel on i.id=rel.itemid '
  153. . ' LEFT JOIN #__users AS u ON u.id = i.created_by'
  154. . $where
  155. . " GROUP BY rel.itemid "
  156. . $orderby
  157. ;
  158. $db->setQuery($query);
  159. //echo $query; //exit();
  160. $items_arr = $db->loadObjectList();
  161. if (!$items_arr) $items_arr = array();
  162. if($db->getErrorNum()) {
  163. echo $db->getErrorMsg();
  164. $filter->html = '';
  165. return false;
  166. }
  167. require_once(JPATH_ROOT.DS."components".DS."com_flexicontent".DS."classes".DS."flexicontent.categories.php");
  168. $tree = flexicontent_cats::getCategoriesTree();
  169. if ($allowed_cats) {
  170. foreach ($allowed_cats as $catid) {
  171. $allowedtree[$catid] = $tree[$catid];
  172. }
  173. }
  174. if ($disallowed_cats) {
  175. foreach ($disallowed_cats as $catid) {
  176. unset($tree[$catid]);
  177. }
  178. $allowedtree = & $tree;
  179. }
  180. if (!$allowed_cats && !$disallowed_cats) {
  181. $allowedtree = & $tree;
  182. }
  183. //echo "<pre>"; foreach ($tree as $index => $cat) echo "$index\n";
  184. //exit();
  185. $ri_field_name = str_replace('-','_',$field->name);
  186. $field->html .= "<div style='float:left;margin-right:16px;'>Select Category:<br>\n";
  187. $field->html .= flexicontent_cats::buildcatselect($allowedtree, $ri_field_name.'_fccats', $catvals="", false, ' class="inputbox" '.$size, true);
  188. $field->html .= "</div>\n";
  189. $field->html .= "&nbsp;&nbsp;&nbsp;";
  190. $field->html .= "<div style='float:left;margin-right:16px;'>Category Items:<br>\n";
  191. $field->html .= '<select id="'.$ri_field_name.'_visitems" name="'.$ri_field_name.'_visitems[]" multiple="multiple" style="min-width:140px;" class="" '.$size.' >'."\n";
  192. $field->html .= '</select>'."\n";
  193. $field->html .= "</div>\n";
  194. $field->html .= "<div style='float:left;margin-right:16px;'><br>\n";
  195. $field->html .= '<a href="JavaScript:void(0);" id="btn-add_'.$ri_field_name.'">Add &raquo;</a><br>'."\n";
  196. $field->html .= '<a href="JavaScript:void(0);" id="btn-remove_'.$ri_field_name.'">&laquo; Remove</a><br>'."\n";
  197. if ($title_filter) {
  198. $document = &JFactory::getDocument();
  199. $document->addScript( JURI::root().'administrator/components/com_flexicontent/assets/js/filterlist.js' );
  200. $field->html.= '
  201. <br /><input id="'.$ri_field_name.'_regexp" name="'.$ri_field_name.'_regexp" onKeyUp="'.$ri_field_name.'_titlefilter.set(this.value)" size="20" />
  202. <br /><input type="button" onClick="'.$ri_field_name.'_titlefilter.set(this.form.'.$ri_field_name.'_regexp.value)" value="'.JText::_('FLEXI_RIFLD_FILTER').'" style="margin-top:6px;" />
  203. <input type="button" onClick="'.$ri_field_name.'_titlefilter.reset();this.form.'.$ri_field_name.'_regexp.value=\'\'" value="'.JText::_('FLEXI_RIFLD_RESET').'" style="margin-top:6px;" />
  204. <script type="text/javascript">
  205. <!--
  206. var filteredfield = document.getElementById("'.$ri_field_name.'_visitems");
  207. var '.$ri_field_name.'_titlefilter = new filterlist( filteredfield );
  208. //-->
  209. </script>
  210. ';
  211. }
  212. $field->html .= "</div>\n";
  213. // The split up the items
  214. $items_options = '';
  215. $items_options_select = '';
  216. $items_options_unused = '';
  217. $state_shortname = array(1=>'P', 0=>'U', -1=>'A', -3=>'PE', -4=>'OQ', -5=>'IP');
  218. foreach($items_arr as $itemdata) {
  219. $itemtitle = (mb_strlen($itemdata->title) > $maxtitlechars) ? mb_substr($itemdata->title,0,$maxtitlechars) . "..." : $itemdata->title;
  220. if ($prepend_item_state) {
  221. $statestr = "[". @$state_shortname[$itemdata->state]."] ";
  222. $itemtitle = $statestr.$itemtitle." ";//.$itemdata->catlist;
  223. }
  224. $itemcat_arr = explode(",", $itemdata->catlist);
  225. $classes_str = "";
  226. $itemid = $itemdata->id;
  227. foreach ($itemcat_arr as $catid) $classes_str .= " "."cat_".$catid;
  228. if ( isset($fieldval[$itemid]) ) {
  229. $items_options .= '<option class="'.$classes_str.'" value="'.$fieldval[$itemid]->val.'" >'.$itemtitle.'</option>'."\n";
  230. $items_options_select .= '<option selected="selected" class="'.$classes_str.'" value="'.$fieldval[$itemid]->val.'" >'.$itemtitle.'</option>'."\n";
  231. } else {
  232. $items_options_unused .= '<option class="'.$classes_str.'" value="'.$itemid.'" >'.$itemtitle.'</option>'."\n";
  233. }
  234. }
  235. $fieldname = FLEXI_J16GE ? 'custom['.$ri_field_name.'][]' : $ri_field_name.'[]';
  236. $field->html .= "<div style='float:left;margin-right:16px;'>Related Items<br>\n";
  237. $field->html .= '<select id="'.$ri_field_name.'" name="'.$fieldname.'" multiple="multiple" class="'.$required.'" style="min-width:140px;display:none;" '.$size.' >';
  238. $field->html .= $items_options_select;
  239. $field->html .= '</select>'."\n";
  240. $field->html .= '<select id="'.$ri_field_name.'_selitems" name="'.$ri_field_name.'_selitems[]" multiple="multiple" style="min-width:140px;" '.$size.' >';
  241. $field->html .= $items_options;
  242. $field->html .= '</select>'."\n";
  243. $field->html .= "</div>\n";
  244. $field->html .= '<select id="'.$ri_field_name.'_hiditems" name="'.$ri_field_name.'_hiditems" style="display:none;" >';
  245. $field->html .= $items_options_unused;
  246. $field->html .= '</select>'."\n";
  247. $js= "
  248. window.addEvent( 'domready', function() {
  249. jQuery('#btn-add_".$ri_field_name."').click(function(){
  250. jQuery('#".$ri_field_name."_visitems option:selected').each( function() {
  251. jQuery('#".$ri_field_name."_selitems').append(\"<option class='\"+jQuery(this).attr('class')+\"' value='\"+jQuery(this).val()+\"'>\"+jQuery(this).text()+\"</option>\");
  252. jQuery('#".$ri_field_name."').append(\"<option selected='selected' class='\"+jQuery(this).attr('class')+\"' value='\"+jQuery(this).val()+\"'>\"+jQuery(this).text()+\"</option>\");
  253. jQuery(this).remove();
  254. });
  255. });
  256. jQuery('#btn-remove_".$ri_field_name."').click(function(){
  257. jQuery('#".$ri_field_name."_selitems option:selected').each( function() {
  258. jQuery('#".$ri_field_name."_visitems').append(\"<option class='\"+jQuery(this).attr('class')+\"' value='\"+jQuery(this).val()+\"'>\"+jQuery(this).text()+\"</option>\");
  259. jQuery(\"#".$ri_field_name." option[value='\"+jQuery(this).val()+\"']\").remove();
  260. jQuery(this).remove();
  261. });
  262. });
  263. });
  264. window.addEvent( 'domready', function() {
  265. $('".$ri_field_name."_fccats').addEvent( 'change', function() {
  266. ". ( $title_filter ? $ri_field_name."_titlefilter.reset(); this.form.".$ri_field_name."_regexp.value='';" : "" ) . "
  267. jQuery('#".$ri_field_name."_visitems option').each( function() {
  268. var data = jQuery(this).val().split(':');
  269. var itemid = data[0];
  270. jQuery('#".$ri_field_name."_hiditems').append(\"<option class='\"+jQuery(this).attr('class')+\"' value='\"+itemid+\"'>\"+jQuery(this).text()+\"</option>\");
  271. jQuery(this).remove();
  272. });
  273. jQuery('#".$ri_field_name."_hiditems option').each( function() {
  274. if ( jQuery(this).hasClass('cat_' + jQuery('#".$ri_field_name."_fccats').attr('value') ) ) {
  275. jQuery('#".$ri_field_name."_visitems').append(\"<option class='\"+jQuery(this).attr('class')+\"'value='\"+jQuery(this).val()+\":\"+jQuery('#".$ri_field_name."_fccats').val()+\"'>\"+jQuery(this).text()+\"</option>\");
  276. jQuery(this).remove();
  277. }
  278. });
  279. ". ( $title_filter ? $ri_field_name."_titlefilter.init();" : "" ) . "
  280. });
  281. });";
  282. $doc = & JFactory::getDocument();
  283. $doc->addScriptDeclaration( $js );
  284. }
  285. // Method to create field's HTML display for frontend views
  286. function onDisplayFieldValue(&$field, $item, $values=null, $prop='display')
  287. {
  288. // execute the code only if the field type match the plugin type
  289. if($field->field_type != 'relateditems') return;
  290. $field->label = JText::_($field->label);
  291. $field->{$prop} = '';
  292. $values = $values ? $values : $field->value;
  293. // Compatibility with old values, we no longer serialize all values to one, this way the field can be reversed !!!
  294. $values = ( $field_data = @unserialize($values) ) ? $field_data : $field->value;
  295. // No related items, return
  296. if ( !$values || !count($values) ) return;
  297. $fieldval = array();
  298. foreach($values as $i => $val) {
  299. //echo $val."<br>";
  300. list ($itemid,$catid) = explode(":", $val);
  301. $fieldval[$itemid] = new stdClass();
  302. $fieldval[$itemid]->itemid = $itemid;
  303. $fieldval[$itemid]->catid = $catid;
  304. $fieldval[$itemid]->val = $val;
  305. }
  306. $values = $fieldval;
  307. // Execute query to get item list data
  308. $db = & JFactory::getDBO();
  309. $query = $this->_createItemsQuery($field, $item, $isform=0, $values);
  310. $db->setQuery($query);
  311. $item_list = & $db->loadObjectList('id');
  312. $field->value_item_list = & $item_list;
  313. //echo "<pre>"; print_r($item_list); echo "</pre>";
  314. if ($db->getErrorNum()) {
  315. //echo $db->getErrorMsg();
  316. $field->{$prop} = 'Field [id:'.$field->id.'] : SQL query error: '.$db->getErrorMsg();
  317. return;
  318. }
  319. // No published related items or SQL query failed, return
  320. if ( !$item_list ) return;
  321. $field->{$prop} = $this->_createItemsList($field, $item, $values, $item_list, $isform=0);
  322. }
  323. // Helper private method to create SQL query for retrieving items list data
  324. function &_createItemsQuery(&$field, &$item, $isform=0, $values=null)
  325. {
  326. $db = & JFactory::getDBO();
  327. $order = $field->parameters->get( $isform ? 'orderby_form' : 'orderby', 'alpha' );
  328. // Get data like aliases and published state
  329. $publish_where = '';
  330. if ($field->parameters->get('use_publish_dates', 1 )) {
  331. $nullDate = $db->getNullDate();
  332. $mainframe =& JFactory::getApplication();
  333. $now = $mainframe->get('requestTime');
  334. $publish_where = ' AND ( i.publish_up = '.$db->Quote($nullDate).' OR i.publish_up <= '.$db->Quote($now).' )';
  335. $publish_where .= ' AND ( i.publish_down = '.$db->Quote($nullDate).' OR i.publish_down >= '.$db->Quote($now).' )';
  336. }
  337. $orderby = $this->_buildItemOrderBy($order);
  338. //$query = 'SELECT i.title, i.id, i.alias, i.state, i.catid, '
  339. $query = 'SELECT i.*, ext.type_id,'
  340. .' GROUP_CONCAT(c.id SEPARATOR ",") AS catidlist, '
  341. .' GROUP_CONCAT(c.alias SEPARATOR ",") AS cataliaslist '
  342. .' FROM #__content AS i '
  343. .' LEFT JOIN #__flexicontent_items_ext AS ext ON i.id=ext.item_id '
  344. .' LEFT JOIN #__flexicontent_cats_item_relations AS rel ON i.id=rel.itemid '
  345. .' LEFT JOIN #__categories AS c ON c.id=rel.catid '
  346. .' LEFT JOIN #__users AS u ON u.id = i.created_by'
  347. .' WHERE i.id IN ('. implode(",", array_keys($values)) .')'
  348. . $publish_where
  349. .' GROUP BY i.id '
  350. . $orderby
  351. ;
  352. //echo "<pre>".$query."</pre>";
  353. return $query;
  354. }
  355. // Build the order clause
  356. function &_createItemsList(&$field, &$item, $values, &$item_list, $isform=0)
  357. {
  358. $db = & JFactory::getDBO();
  359. global $globalcats;
  360. global $globalnoroute;
  361. if (!is_array($globalnoroute)) $globalnoroute = array();
  362. // Get fields of type relateditems
  363. static $related_items_fields = null;
  364. if ($related_items_fields===null) {
  365. $query = "SELECT name FROM #__flexicontent_fields WHERE field_type='relateditems'";
  366. $db->setQuery($query);
  367. $field_name_col = FLEXI_J30GE ? $db->loadColumn() : $db->loadResultArray();
  368. $related_items_fields = !$field_name_col ? array() : array_flip($field_name_col);
  369. }
  370. // some parameter shortcuts
  371. $remove_space = $field->parameters->get( 'remove_space', 0 ) ;
  372. $pretext = $field->parameters->get( $isform ? 'pretext_form' : 'pretext', '' ) ;
  373. $posttext = $field->parameters->get( $isform ? 'posttext_form' : 'posttext', '' ) ;
  374. $separatorf = $field->parameters->get( $isform ? 'separator' : 'separatorf' ) ;
  375. $opentag = $field->parameters->get( $isform ? 'opentag_form' : 'opentag', '' ) ;
  376. $closetag = $field->parameters->get( $isform ? 'closetag_form' : 'closetag', '' ) ;
  377. $relitem_html = $field->parameters->get( $isform ? 'relitem_html_form' : 'relitem_html', '__display_text__' ) ;
  378. $displayway = $field->parameters->get( $isform ? 'displayway_form' : 'displayway', 1 ) ;
  379. $addlink = $field->parameters->get( $isform ? 'addlink_form' : 'addlink', 1 ) ;
  380. $addtooltip = $field->parameters->get( $isform ? 'addtooltip_form' : 'addtooltip', 1 ) ;
  381. // Parse and identify custom fields
  382. $result = preg_match_all("/\{\{([a-zA-Z_0-9]+)(##)?([a-zA-Z_0-9]+)?\}\}/", $relitem_html, $field_matches);
  383. if ($result) {
  384. $custom_field_names = $field_matches[1];
  385. $custom_field_methods = $field_matches[3];
  386. } else {
  387. $custom_field_names = array();
  388. $custom_field_methods = array();
  389. }
  390. /*echo "Fields for Related Items List: "; $sep = "";
  391. foreach ($custom_field_names as $i => $custom_field_name) {
  392. echo $sep . $custom_field_names[$i] . ($custom_field_methods[$i] ? "->". $custom_field_methods[$i] : ""); $sep = " , ";
  393. }
  394. echo "<br/>\n";*/
  395. // Parse and identify language strings and then make language replacements
  396. $result = preg_match_all("/\%\%([^%]+)\%\%/", $relitem_html, $translate_matches);
  397. if ($result) {
  398. $translate_strings = $translate_matches[1];
  399. } else {
  400. $translate_strings = array('FLEXI_READ_MORE_ABOUT');
  401. }
  402. foreach ($translate_strings as $translate_string) {
  403. $relitem_html = str_replace('%%'.$translate_string.'%%', JText::_($translate_string), $relitem_html);
  404. }
  405. switch($separatorf)
  406. {
  407. case 0:
  408. $separatorf = '&nbsp;';
  409. break;
  410. case 1:
  411. $separatorf = '<br />';
  412. break;
  413. case 2:
  414. $separatorf = '&nbsp;|&nbsp;';
  415. break;
  416. case 3:
  417. $separatorf = ',&nbsp;';
  418. break;
  419. case 4:
  420. $separatorf = $closetag . $opentag;
  421. break;
  422. default:
  423. $separatorf = '&nbsp;';
  424. break;
  425. }
  426. if($pretext) { $pretext = $remove_space ? $pretext : $pretext . ' '; }
  427. if($posttext) { $posttext = $remove_space ? $posttext : ' ' . $posttext; }
  428. global $fc_run_times;
  429. $fc_run_times['render_subfields'][$item->id."_".$field->id] = 0;
  430. foreach($item_list as $result)
  431. {
  432. // Check if related item is published and skip if not published
  433. if ($result->state != 1 && $result->state != -5) continue;
  434. $itemslug = $result->id.":".$result->alias;
  435. $catslug = "";
  436. // Check if removed from category or inside a noRoute category or inside a non-published category
  437. // and use main category slug or other routable & published category slug
  438. $catid_arr = explode(",", $result->catidlist);
  439. $catalias_arr = explode(",", $result->cataliaslist);
  440. for($i=0; $i<count($catid_arr); $i++) {
  441. $itemcataliases[$catid_arr[$i]] = $catalias_arr[$i];
  442. }
  443. $rel_itemid = $result->id;
  444. $rel_catid = isset($values[$rel_itemid]->catid) ? $values[$rel_itemid]->catid : $result->catid;
  445. if ( isset($itemcataliases[$rel_catid]) && !in_array($rel_catid, $globalnoroute) && $globalcats[$rel_catid]->published) {
  446. $catslug = $rel_catid.":".$itemcataliases[$rel_catid];
  447. } else if (!in_array($result->catid, $globalnoroute) && $globalcats[$result->catid]->published ) {
  448. $catslug = $globalcats[$result->catid]->slug;
  449. } else {
  450. foreach ($catid_arr as $catid) {
  451. if ( !in_array($catid, $globalnoroute) && $globalcats[$catid]->published) {
  452. $catslug = $globalcats[$catid]->slug;
  453. break;
  454. }
  455. }
  456. }
  457. $result->slug = $itemslug;
  458. $result->categoryslug = $catslug;
  459. }
  460. foreach($custom_field_names as $i => $custom_field_name) {
  461. if ( !isset($related_items_fields[$custom_field_name]) ) {
  462. $display_var = $custom_field_methods[$i] ? $custom_field_methods[$i] : 'display';
  463. $start_microtime = microtime(true);
  464. FlexicontentFields::getFieldDisplay($item_list, $custom_field_name, $custom_field_values=null, $display_var);
  465. $fc_run_times['render_subfields'][$item->id."_".$field->id] += round(1000000 * 10 * (microtime(true) - $start_microtime)) / 10;
  466. } else {
  467. //$custom_field_display = 'cannot replace field: "'.$custom_field_name.'" because it is of type "related_items", which can cause loop';
  468. }
  469. }
  470. $display = array();
  471. foreach($item_list as $result)
  472. {
  473. // Check if related item is published and skip if not published
  474. if ($result->state != 1 && $result->state != -5) continue;
  475. // a. Replace some custom made strings
  476. $item_url = JRoute::_(FlexicontentHelperRoute::getItemRoute($result->slug, $result->categoryslug));
  477. $item_title_escaped = htmlspecialchars($result->title, ENT_COMPAT, 'UTF-8');
  478. $item_tooltip = ' class="hasTip relateditem" title="'. JText::_('FLEXI_READ_MORE_ABOUT').'::'.$item_title_escaped.'" ';
  479. $display_text = $displayway ? $result->title : $result->id;
  480. $display_text = !$addlink ? $display_text : '<a href="'.$item_url.'"'.($addtooltip ? $item_tooltip : '').' >' .$display_text. '</a>';
  481. $curr_relitem_html = $relitem_html;
  482. $curr_relitem_html = str_replace('__item_url__', $item_url, $curr_relitem_html);
  483. $curr_relitem_html = str_replace('__item_title_escaped__', $item_title_escaped, $curr_relitem_html);
  484. $curr_relitem_html = str_replace('__item_tooltip__', $item_tooltip, $curr_relitem_html);
  485. $curr_relitem_html = str_replace('__display_text__', $display_text, $curr_relitem_html);
  486. // b. Replace item properties, e.g. {item->id}, (item->title}, etc
  487. FlexicontentFields::doQueryReplacements($curr_relitem_html, $null_field=null, $result);
  488. // c. Replace HTML display of various item fields
  489. foreach($custom_field_names as $i => $custom_field_name) {
  490. if ( !isset($related_items_fields[$custom_field_name]) ) {
  491. $display_var = $custom_field_methods[$i] ? $custom_field_methods[$i] : 'display';
  492. $custom_field_display = $result->fields[$custom_field_name]->{$display_var};
  493. } else {
  494. $custom_field_display = 'cannot replace field: "'.$custom_field_name.'" because it is of type "related_items", which can cause loop';
  495. }
  496. $custom_field_str = $custom_field_name . ($custom_field_methods[$i] ? "##".$custom_field_methods[$i] : "");
  497. $curr_relitem_html = str_replace('{{'.$custom_field_str.'}}', $custom_field_display, $curr_relitem_html);
  498. }
  499. $display[] = trim($pretext . $curr_relitem_html . $posttext);
  500. }
  501. $display = $opentag . implode($separatorf, $display) . $closetag;
  502. return $display;
  503. }
  504. // **************************************************************
  505. // METHODS HANDLING before & after saving / deleting field events
  506. // **************************************************************
  507. // Method to handle field's values before they are saved into the DB
  508. function onBeforeSaveField( &$field, &$post, &$file, &$item )
  509. {
  510. // execute the code only if the field type match the plugin type
  511. if($field->field_type != 'relateditems') return;
  512. if(!is_array($post) && !strlen($post)) return;
  513. }
  514. // Method to take any actions/cleanups needed after field's values are saved into the DB
  515. function onAfterSaveField( &$field, &$post, &$file, &$item ) {
  516. }
  517. // Method called just before the item is deleted to remove custom item data related to the field
  518. function onBeforeDeleteField(&$field, &$item) {
  519. }
  520. // *********************************
  521. // CATEGORY/SEARCH FILTERING METHODS
  522. // *********************************
  523. // Method to display a category filter for the category view
  524. /*function onDisplayFilter(&$filter, $value='', $formName='adminForm')
  525. {
  526. // execute the code only if the field type match the plugin type
  527. if($filter->field_type != 'relateditems_backlinks') return;
  528. // some parameter shortcuts
  529. $field_id = $filter->id;
  530. $db =& JFactory::getDBO();
  531. $field_elements= 'SELECT DISTINCT fir.item_id as value, i.title as text'
  532. .' FROM #__content as i'
  533. .' LEFT JOIN #__flexicontent_fields_item_relations as fir ON i.id=fir.item_id AND fir.field_id='.$field_id
  534. ;
  535. $db->setQuery($query);
  536. $results = $db->loadObjectList();
  537. echo $db->getErrorMsg();
  538. if (!$results) {
  539. $filter->html = '';
  540. } else {
  541. $options = array();
  542. $options[] = JHTML::_('select.option', '', '-'.JText::_('All').'-');
  543. foreach($results as $result) {
  544. $options[] = JHTML::_('select.option', $result->value, $result->text);
  545. }
  546. $filter->html = JHTML::_('select.genericlist', $options, 'filter_'.$filter->id, ' class="fc_field_filter" onchange="document.getElementById(\''.$formName.'\').submit();"', 'value', 'text', $value);
  547. }
  548. }*/
  549. // **********************
  550. // VARIOUS HELPER METHODS
  551. // **********************
  552. // Build the order clause
  553. function _buildItemOrderBy($order)
  554. {
  555. $params = & $field->parameters;
  556. $filter_order = '';
  557. $filter_order_dir = '';
  558. if ($order) {
  559. switch ($order) {
  560. case 'date' :
  561. $filter_order = 'i.created';
  562. $filter_order_dir = 'ASC';
  563. break;
  564. case 'rdate' :
  565. $filter_order = 'i.created';
  566. $filter_order_dir = 'DESC';
  567. break;
  568. case 'modified' :
  569. $filter_order = 'i.modified';
  570. $filter_order_dir = 'DESC';
  571. break;
  572. case 'alpha' :
  573. $filter_order = 'i.title';
  574. $filter_order_dir = 'ASC';
  575. break;
  576. case 'ralpha' :
  577. $filter_order = 'i.title';
  578. $filter_order_dir = 'DESC';
  579. break;
  580. case 'author' :
  581. $filter_order = 'u.name';
  582. $filter_order_dir = 'ASC';
  583. break;
  584. case 'rauthor' :
  585. $filter_order = 'u.name';
  586. $filter_order_dir = 'DESC';
  587. break;
  588. case 'hits' :
  589. $filter_order = 'i.hits';
  590. $filter_order_dir = 'ASC';
  591. break;
  592. case 'rhits' :
  593. $filter_order = 'i.hits';
  594. $filter_order_dir = 'DESC';
  595. break;
  596. case 'order' :
  597. $filter_order = 'rel.ordering';
  598. $filter_order_dir = 'ASC';
  599. break;
  600. }
  601. }
  602. if ($filter_order)
  603. $orderby = ' ORDER BY '.$filter_order.' '.$filter_order_dir.', i.title';
  604. else
  605. $orderby = ' ORDER BY i.title';
  606. return $orderby;
  607. }
  608. }