From 4b443bc2c83d2f0b6d2534530337047cdba71ac5 Mon Sep 17 00:00:00 2001 From: Cameron Date: Wed, 18 Jan 2017 17:10:12 -0800 Subject: [PATCH] Experimental Feature: Page/Menu custom fields. Enable debug to experiment. Usage: {CPAGEFIELD: name=xxxxx} where 'name' is the field name. Currently only functions in edit mode when the chapter is already set. --- e107_admin/cpage.php | 239 +++++++++++++++++- .../shortcodes/batch/page_shortcodes.php | 64 ++++- e107_core/sql/core_sql.php | 2 + e107_core/templates/page_template.php | 6 +- e107_handlers/form_handler.php | 18 +- e107_handlers/model_class.php | 4 + 6 files changed, 318 insertions(+), 15 deletions(-) diff --git a/e107_admin/cpage.php b/e107_admin/cpage.php index 4836f9922..c07a1254d 100644 --- a/e107_admin/cpage.php +++ b/e107_admin/cpage.php @@ -161,11 +161,11 @@ class page_chapters_ui extends e_admin_ui 'chapter_meta_description' => array('title'=> LAN_DESCRIPTION, 'type' => 'textarea', 'width' => 'auto', 'thclass' => 'left','readParms' => 'expand=...&truncate=150&bb=1', 'writeParms'=>'size=xxlarge', 'readonly'=>FALSE), 'chapter_meta_keywords' => array('title'=> LAN_KEYWORDS, 'type' => 'tags', 'inline'=>true, 'width' => 'auto', 'thclass' => 'left', 'readonly'=>FALSE), - 'chapter_sef' => array('title'=> LAN_SEFURL, 'type' => 'text', 'width' => 'auto', 'readonly'=>FALSE, 'inline'=>true, 'writeParms'=>'size=xxlarge&inline-empty=1'), // Display name + 'chapter_sef' => array('title'=> LAN_SEFURL, 'type' => 'text', 'width' => 'auto', 'readonly'=>FALSE, 'inline'=>true, 'writeParms'=>'size=xxlarge&inline-empty=1&sef=chapter_name'), // Display name 'chapter_manager' => array('title'=> CUSLAN_55, 'type' => 'userclass', 'inline'=>true, 'width' => 'auto', 'data' => 'int','batch'=>TRUE, 'filter'=>TRUE), 'chapter_order' => array('title'=> LAN_ORDER, 'type' => 'text', 'width' => 'auto', 'thclass' => 'right', 'class'=> 'right' ), 'chapter_visibility' => array('title'=> LAN_VISIBILITY, 'type' => 'userclass', 'inline'=>true, 'width' => 'auto', 'data' => 'int','batch'=>TRUE, 'filter'=>TRUE), - + 'chapter_fields' => array('title', 'hidden', 'type'=>'hidden'), 'options' => array('title'=> LAN_OPTIONS, 'type' => 'method', 'width' => '10%', 'forced'=>TRUE, 'thclass' => 'center last', 'class' => 'left', 'readParms'=>'sort=1') ); @@ -177,6 +177,15 @@ class page_chapters_ui extends e_admin_ui function init() { + if(e_DEBUG === true) + { + e107::getMessage()->addWarning("Experimental: Custom Fields"); + $this->tabs = array(LAN_GENERAL,"Custom Fields"); + $this->fields['chapter_fields'] = array('title'=>"Fields", 'tab'=>1, 'type'=>'method', 'data'=>'json', 'writeParms'=>array('nolabel'=>2)); + } + + + if($this->getAction() == 'list') { $this->fields['chapter_parent']['title'] = CUSLAN_56; @@ -237,7 +246,38 @@ class page_chapters_ui extends e_admin_ui public function beforeUpdate($new_data, $old_data, $id) { - // return $this->beforeCreate($new_data); + // return $this->beforeCreate($new_data); + + $new_data['chapter_fields'] = $this->processCustomFields($new_data['chapter_fields']); + + return $new_data; + } + + + private function processCustomFields($newdata) + { + if(empty($newdata)) + { + return null; + } + + $new = array(); + foreach($newdata as $fields) + { + if(empty($fields['key']) || empty($fields['type'])) + { + continue; + } + + + $key = $fields['key']; + unset($fields['key']); + $new[$key] = $fields; + + + } + + return $new; } } @@ -280,7 +320,72 @@ class page_chapters_form_ui extends e_admin_form_ui } - + function chapter_fields($curVal,$mode,$parm) + { + + $frm = e107::getForm(); + + if($mode == 'read') + { + + } + + if($mode == 'write') + { + + $value= array(); + + if(!empty($curVal)) + { + $curVal = e107::unserialize($curVal); + $i = 0; + foreach($curVal as $k=>$v) + { + $v['key'] = $k; + $value[$i] = $v; + $i++; + } + } + + + $text = " + + + + + + + + + "; + + for ($i = 0; $i <= 10; $i++) + { + $fieldName = $this->text('chapter_fields['.$i.'][key]',$value[$i]['key'],30, array('pattern'=>'^[a-z0-9-]*')); + $fieldTitle = $this->text('chapter_fields['.$i.'][title]',$value[$i]['title'], 80); + $fieldType = $this->select('chapter_fields['.$i.'][type]',$this->getFieldTypes(),$value[$i]['type'], 'useValues=1&default=blank'); + $fieldParms = $this->text('chapter_fields['.$i.'][writeParms]',$value[$i]['writeParams'], 80, array('size'=>'xxlarge')); + + $text .= ""; + } + + $text .= "
".LAN_NAME."".LAN_TITLE."".LAN_TYPE."Params
".$fieldName."".$fieldTitle."".$fieldType."".$fieldParms."
"; + + $text .= print_a($value,true); + + + return $text; + } + + if($mode == 'filter') + { + return; + } + if($mode == 'batch') + { + return; + } + } @@ -473,7 +578,7 @@ class page_admin_ui extends e_admin_ui // PAGE LIST/EDIT and MENU EDIT modes. protected $fields = array( 'checkboxes' => array('title'=> '', 'type' => null, 'width' =>'3%', 'forced'=> TRUE, 'thclass'=>'center', 'class'=>'center'), - 'page_id' => array('title'=> LAN_ID, 'type' => 'text', 'tab' => 0, 'width'=>'5%', 'forced'=> TRUE, 'readParms'=>'link=sef&target=dialog'), + 'page_id' => array('title'=> LAN_ID, 'type' => 'text', 'tab' => 0, 'width'=>'5%', 'forced'=> TRUE, 'readParms'=>'link=sef&target=blank'), 'page_title' => array('title'=> LAN_TITLE, 'tab' => 0, 'type' => 'text', 'inline'=>true, 'width'=>'25%', 'writeParms'=>'size=block-level'), 'page_chapter' => array('title'=> CUSLAN_63, 'tab' => 0, 'type' => 'dropdown', 'width' => '20%', 'filter' => true, 'batch'=>true, 'inline'=>true), @@ -494,7 +599,9 @@ class page_admin_ui extends e_admin_ui 'page_metadscr' => array('title'=> CUSLAN_11, 'tab' => 1, 'type' => 'text', 'width' => 'auto', 'writeParms'=>'size=xxlarge'), 'page_order' => array('title'=> LAN_ORDER, 'tab' => 1, 'type' => 'number', 'width' => 'auto', 'inline'=>true), - + 'page_fields' => array('title'=>'Custom Fields', 'tab'=>4, 'type'=>'hidden', 'data'=>'json', 'width'=>'auto'), + + // Menu Tab XXX 'menu_name' is 'menu_name' - not caption. 'menu_name' => array('title'=> CUSLAN_64, 'tab' => 2, 'type' => 'text', 'width' => 'auto','nolist'=>true, "help"=>"Will be listed in the Menu-Manager under this name or may be called using {CMENU=name} in your theme. Must use ASCII characters only and be all lowercase."), 'menu_title' => array('title'=> CUSLAN_65, 'nolist'=>true, 'tab' => 2, 'type' => 'text', 'inline'=>true, 'width'=>'25%', "help"=>"Caption displayed on the menu item.", 'writeParms'=>'size=xxlarge'), @@ -528,9 +635,13 @@ class page_admin_ui extends e_admin_ui protected $books = array(); protected $cats = array(0 => LAN_NONE); protected $templates = array(); + protected $chapterFields = array(); function init() { + + + if(vartrue($_POST['menu_delete'])) // Delete a Menu (or rather, remove it's data ) { @@ -543,7 +654,7 @@ class page_admin_ui extends e_admin_ui } // USED IN Menu LIST/INLINE-EDIT MODE ONLY. - if($this->getMode() == 'menu' && ($this->getACtion() == 'list' || $this->getACtion() == 'inline')) + if($this->getMode() == 'menu' && ($this->getAction() == 'list' || $this->getAction() == 'inline')) { $this->listQry = "SELECT SQL_CALC_FOUND_ROWS p.*,u.user_id,u.user_name FROM #page AS p LEFT JOIN #user AS u ON p.page_author = u.user_id WHERE p.menu_name != '' "; // without any Order or Limit. @@ -629,8 +740,8 @@ class page_admin_ui extends e_admin_ui $sql = e107::getDb(); - - $sql->gen("SELECT chapter_id,chapter_name,chapter_parent FROM #page_chapters ORDER BY chapter_parent asc, chapter_order"); + $chapterFields = array(); + $sql->gen("SELECT chapter_id,chapter_name,chapter_parent, chapter_fields FROM #page_chapters ORDER BY chapter_parent asc, chapter_order"); while($row = $sql->fetch()) { $cat = $row['chapter_id']; @@ -643,16 +754,111 @@ class page_admin_ui extends e_admin_ui { $book = $row['chapter_parent']; $this->cats[$cat] = $this->books[$book] . " : ".$row['chapter_name']; - } + } + + if(!empty($row['chapter_fields'])) + { + $this->chapterFields[$cat] = e107::unserialize($row['chapter_fields']); + } + + } // asort($this->cats); $this->fields['page_chapter']['writeParms']['optArray'] = $this->cats; $this->fields['page_chapter']['writeParms']['size'] = 'xxlarge'; + if(e_DEBUG === true && $this->getAction() === 'edit') + { + // $this->initCustomFields(); + } + + + } + private function initCustomFields() + { + $row = e107::getDb()->retrieve('page', 'page_chapter, page_fields', 'page_id='.$this->getId()); + + $chap = intval($row['page_chapter']); + + $this->tabs[] = "Additional Fields"; + + $curVal = e107::unserialize($row['page_fields']); + + $tabCount = count($this->tabs) -1; + + $this->getModel()->set('page_fields', null); + + if(!empty($this->chapterFields[$chap])) + { + + foreach($this->chapterFields[$chap] as $key=>$fld) + { + $fld['tab'] = $tabCount; + $fld['data'] = false; + + $this->fields['page_fields__'.$key] = $fld; + + $this->getModel()->set('page_fields__'.$key, $curVal[$key]); + } + } + + + } + + // Override default so we can alter the field db table data after it is loaded. . + function EditObserver() + { + $this->getModel()->load($this->getId()); + $this->addTitle(); + + if(e_DEBUG !== true) + { + return; + } + + $this->initCustomFields(); + + + } + + /** + * Filter/Process Posted page_field data; + * @param $new_data + * @return null + */ + private function processCustomFieldData($new_data) + { + if(empty($new_data)) + { + return null; + } + + unset($new_data['page_fields']); // Reset. + + foreach($new_data as $k=>$v) + { + if(substr($k,0,11) === "page_fields") + { + list($tmp,$newkey) = explode("__",$k); + $new_data['page_fields'][$newkey] = $v; + unset($new_data[$k]); + + + } + + } + + + + return $new_data; + + + } + /** * Overrid */ @@ -721,7 +927,10 @@ class page_admin_ui extends e_admin_ui $newdata['page_sef'] = eHelper::secureSef($newdata['page_sef']); } - + + // $newdata = $this->processCustomFieldData($newdata); + + $sef = e107::getParser()->toDB($newdata['page_sef']); if(isset($newdata['page_title']) && isset($newdata['menu_name']) && empty($newdata['page_title']) && empty($newdata['menu_name'])) @@ -742,11 +951,17 @@ class page_admin_ui extends e_admin_ui function beforeUpdate($newdata,$olddata, $id) { + + $newdata = $this->processCustomFieldData($newdata); + if(isset($newdata['menu_name'])) { $newdata['menu_name'] = preg_replace('/[^\w-*]/','',$newdata['menu_name']); } + + + return $newdata; } @@ -781,6 +996,8 @@ class page_admin_ui extends e_admin_ui } + + public function afterDelete($deleted_data, $id, $deleted_check) { $sql = e107::getDb(); diff --git a/e107_core/shortcodes/batch/page_shortcodes.php b/e107_core/shortcodes/batch/page_shortcodes.php index be293d22a..5b7a397b9 100644 --- a/e107_core/shortcodes/batch/page_shortcodes.php +++ b/e107_core/shortcodes/batch/page_shortcodes.php @@ -33,9 +33,17 @@ class cpage_shortcodes extends e_shortcode foreach($books as $row) { $id = $row['chapter_id']; + + if(!empty($row['chapter_fields'])) + { + $row['chapter_fields'] = e107::unserialize($row['chapter_fields']); + } + $this->chapterData[$id] = $row; } - + + + } @@ -596,5 +604,57 @@ class cpage_shortcodes extends e_shortcode return "".$icon.""; } - + + + /** + * Return raw HTML-usable values from page fields. + * @experimental subject to change without notice. + * @param null $parm + * @return mixed + */ + function sc_cpagefield($parm=null) + { + if(empty($parm['name']) || empty($this->var['page_fields'])) + { + return null; + } + + $tp = e107::getParser(); + + $chap = $this->var['page_chapter']; + $key = $parm['name']; + $fields = $this->chapterData[$chap]['chapter_fields']; + $fieldData = e107::unserialize($this->var['page_fields']); + $type = $fields[$key]['type'];; + + // @todo Move this part to form_handler somewhere. + if(isset($fieldData[$key])) + { + $value = $fieldData[$key]; + + switch($type) + { + case "image": + return $tp->toImage($value); + break; + + case "icon": + return $tp->toIcon($value); + break; + + default: + return $tp->toHtml($value); + } + + } + + + + } + + + + + + } diff --git a/e107_core/sql/core_sql.php b/e107_core/sql/core_sql.php index 6a2f9aeb3..bfcc84d5b 100644 --- a/e107_core/sql/core_sql.php +++ b/e107_core/sql/core_sql.php @@ -387,6 +387,7 @@ CREATE TABLE page ( page_ip_restrict text, page_template varchar(50) NOT NULL default '', page_order int(4) unsigned NOT NULL default '9999', + page_fields mediumtext, menu_name varchar(50) NOT NULL default '', menu_title varchar(250) NOT NULL default '', menu_text mediumtext, @@ -418,6 +419,7 @@ CREATE TABLE page_chapters ( chapter_order int(6) unsigned NOT NULL default '0', chapter_template varchar(50) NOT NULL default '', chapter_visibility tinyint(3) unsigned NOT NULL default '0', + chapter_fields mediumtext, PRIMARY KEY (chapter_id), KEY chapter_order (chapter_order) ) ENGINE=MyISAM; diff --git a/e107_core/templates/page_template.php b/e107_core/templates/page_template.php index 026f3a0fd..19a9ae2d7 100644 --- a/e107_core/templates/page_template.php +++ b/e107_core/templates/page_template.php @@ -51,7 +51,11 @@ $sc_style['CPAGENAV|default']['post'] = '';
{CPAGERATING|default} {CPAGEEDIT} - '; + + + '; + + // {CPAGEFIELD: name=image} $PAGE_WRAPPER['default']['CPAGEEDIT'] = "
{---}
"; diff --git a/e107_handlers/form_handler.php b/e107_handlers/form_handler.php index 8a563011f..76af9b5ab 100644 --- a/e107_handlers/form_handler.php +++ b/e107_handlers/form_handler.php @@ -67,6 +67,13 @@ class e_form protected $_tabindex_enabled = true; protected $_cached_attributes = array(); + private $fields = array( + 'number', 'email', 'url', 'password', 'text', 'tags', 'textarea', + 'bbarea', 'image', 'file', 'icon', 'datestamp', 'checkboxes', 'dropdown', 'radio', + 'userclass', 'user', 'boolean', 'checkbox', 'hidden', 'lanlist', 'language', 'country' + + ); + /** * @var user_class */ @@ -3011,6 +3018,15 @@ e107::getDebug()->log($sc_parameters); return false; } + + protected function getFieldTypes() + { + asort($this->fields); + return $this->fields; + } + + + /** * Helper function to get default button class by action. * @@ -5770,7 +5786,7 @@ e107::getDebug()->log($sc_parameters); $text .= " "; - $text .= "
".$leftCell."
"; + $text .= (varset($writeParms['nolabel']) == 2) ? '' : "
".$leftCell."
" ; $text .= $rightCell." diff --git a/e107_handlers/model_class.php b/e107_handlers/model_class.php index 3b98e82f0..781b3c711 100644 --- a/e107_handlers/model_class.php +++ b/e107_handlers/model_class.php @@ -2659,6 +2659,10 @@ class e_front_model extends e_model return $tp->toDB($value); break; + case 'json': + return e107::serialize($value,'json'); + break; + case 'code': return $tp->toDB($value, false, false, 'pReFs'); break;