From f2ba89e93a86ef27cc984c1aa308a4fbb4fc0841 Mon Sep 17 00:00:00 2001 From: Roman Klein Date: Mon, 29 Jan 2018 18:50:41 +0100 Subject: [PATCH 1/4] Version 1.2.0 - Code cleanup & reformatting - PHP 7.0 compatibility - Symphony 2.6 & 2.7 compatibility - Added field settings validation --- extension.driver.php | 110 ++++--- fields/field.incremental_number.php | 442 +++++++++++++++++++--------- 2 files changed, 374 insertions(+), 178 deletions(-) mode change 100755 => 100644 extension.driver.php mode change 100755 => 100644 fields/field.incremental_number.php diff --git a/extension.driver.php b/extension.driver.php old mode 100755 new mode 100644 index 6845291..8bf2bd6 --- a/extension.driver.php +++ b/extension.driver.php @@ -1,33 +1,77 @@ -query("DROP TABLE `tbl_fields_incremental_number`"); - } - catch( Exception $e ){ - } - - return true; - } - - - public function install(){ - try{ - Symphony::Database()->query( - "CREATE TABLE `tbl_fields_incremental_number` ( - `id` int(11) unsigned NOT NULL auto_increment, - `field_id` int(11) unsigned NOT NULL, - `start_number` int(11) unsigned NOT NULL, - PRIMARY KEY (`id`), - UNIQUE KEY `field_id` (`field_id`) - ) TYPE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;" - ); - } catch( Exception $e ){ - } - - return true; - } - } +query(" + CREATE TABLE IF NOT EXISTS `$tbl` ( + `id` int(11) unsigned NOT NULL auto_increment, + `field_id` int(11) unsigned NOT NULL, + `start_number` int(11) unsigned NOT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `field_id` (`field_id`) + ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; + "); + } + + /** + * + * uninstall + * + * @since version 1.0.0 + */ + + public function uninstall() + { + return self::deleteFieldTable(); + } + + /** + * + * delete the field table + * + * @since version 1.2.0 + */ + + public static function deleteFieldTable() + { + $tbl = self::FIELD_TBL_NAME; + + return Symphony::Database()->query(" + DROP TABLE IF EXISTS `$tbl` + "); + } + +} diff --git a/fields/field.incremental_number.php b/fields/field.incremental_number.php old mode 100755 new mode 100644 index 84375b3..14462f8 --- a/fields/field.incremental_number.php +++ b/fields/field.incremental_number.php @@ -1,147 +1,299 @@ _name = 'Incremental Number'; - $this->_required = true; - $this->set('required', 'yes'); - } - - function isSortable(){ - return true; - } - - function canFilter(){ - return true; - } - - function allowDatasourceParamOutput(){ - return true; - } - - function canPrePopulate(){ - return true; - } - - public function displaySettingsPanel(&$wrapper, $errors = NULL){ - parent::displaySettingsPanel($wrapper, $errors); - - $label = Widget::Label(__('Start Number')); - $label->appendChild(WIDGET::Input('fields['.$this->get('sortorder').'][start_number]', $this->get('start_number'))); - $wrapper->appendChild($label); - $this->appendShowColumnCheckbox($wrapper); - } - - public function displayPublishPanel(&$wrapper, $data = NULL, $flagWithError = NULL, $fieldnamePrefix = NULL, $fieldnamePostfix = NULL){ - $value = $data['value']; - $label = Widget::Label($this->get('label')); - - $label->appendChild( - Widget::Input( - 'fields'.$fieldnamePrefix.'['.$this->get('element_name').']'.$fieldnamePostfix, - (string) (strlen($value) != 0 ? $value : $this->getNewNumber()), - 'text', - array('readonly' => 'readonly') - ) - ); - - if( $flagWithError != NULL ) $wrapper->appendChild(Widget::Error($label, $flagWithError)); - else $wrapper->appendChild($label); - } - - public function processRawFieldData($data, &$status, $message, $simulate = false, $entry_id = null){ - if( !$data ) $data = $this->getNewNumber(); - - return parent::processRawFieldData($data, $status, $message, $simulate, $entry_id); - } - - public function getNewNumber(){ - $last_num = Symphony::Database()->fetch(" - SELECT `value` - FROM `tbl_entries_data_".$this->get('id')."` - ORDER BY `value` DESC LIMIT 1 - "); - - return (int) (!empty($last_num)) ? $last_num[0]['value'] + 1 : $this->get('start_number'); - } - - public function commit(){ - if( !parent::commit() ) return false; - - $id = $this->get('id'); - $value = $this->get('start_number'); - - if( $id === false ) return false; - - $fields = array(); - - $fields['field_id'] = $id; - $fields['start_number'] = $value; - - Symphony::Database()->query("DELETE FROM `tbl_fields_".$this->handle()."` WHERE `field_id` = '$id' LIMIT 1"); - - return Symphony::Database()->insert($fields, 'tbl_fields_'.$this->handle()); - - } - - public function displayDatasourceFilterPanel(&$wrapper, $data = NULL, $errors = NULL, $fieldnamePrefix = NULL, $fieldnamePostfix = NULL){ - $wrapper->appendChild(new XMLElement('h4', $this->get('label').' '.$this->Name().'')); - $label = Widget::Label('Value'); - $label->appendChild(Widget::Input('fields[filter]'.($fieldnamePrefix ? '['.$fieldnamePrefix.']' : '').'['.$this->get('id').']'.($fieldnamePostfix ? '['.$fieldnamePostfix.']' : ''), ($data ? General::sanitize($data) : NULL))); - $wrapper->appendChild($label); - - $wrapper->appendChild(new XMLElement('p', 'To filter by ranges, add mysql: to the beginning of the filter input. Use value for field name. E.G. mysql: value >= 1.01 AND value <= {$price}', array('class' => 'help'))); - - } - - public function checkPostFieldData($data, &$message, $entry_id = NULL){ - $message = NULL; - - if( $this->get('required') == 'yes' && strlen($data) == 0 ){ - $message = 'This is a required field.'; - return self::__MISSING_FIELDS__; - } - - if( strlen($data) > 0 && !is_numeric($data) ){ - $message = 'Must be a number.'; - return self::__INVALID_FIELDS__; - } - - return self::__OK__; - } - - public function createTable(){ - return Symphony::Database()->query( - "CREATE TABLE IF NOT EXISTS `tbl_entries_data_".$this->get('id')."` ( - `id` int(11) unsigned NOT NULL auto_increment, - `entry_id` int(11) unsigned NOT NULL, - `value` int(11) default NULL, - PRIMARY KEY (`id`), - KEY `entry_id` (`entry_id`), - KEY `value` (`value`) - ) TYPE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;" - - ); - } - - function buildDSRetrievalSQL($data, &$joins, &$where, $andOperation = false){ - if( preg_match('/^mysql:/i', $data[0]) ){ - - $field_id = $this->get('id'); - - $expression = str_replace(array('mysql:', 'value'), array('', " `t$field_id`.`value` "), $data[0]); - - $joins .= " LEFT JOIN `tbl_entries_data_$field_id` AS `t$field_id` ON (`e`.`id` = `t$field_id`.entry_id) "; - $where .= " AND $expression "; - } - - else parent::buildDSRetrievalSQL($data, $joins, $where, $andOperation); - - return true; - } - - } +if (!defined('__IN_SYMPHONY__')) die('

Symphony Error

You cannot directly access this file

'); + +class fieldincremental_number extends Field +{ + + /*------------------------------------------------------------------------- + DEFINITION + -------------------------------------------------------------------------*/ + + /** + * + * construct + * + * @since version 1.0.0 + */ + + function __construct() + { + // call the parent constructor + parent::__construct(); + + // set the name of the field + $this->_name = 'Incremental Number'; + + // force "required"-setting + $this->_required = true; + $this->set('required', 'yes'); + } + + /** + * + * create table + * + * @since version 1.0.0 + */ + + public function createTable() + { + return Symphony::Database()->query( + "CREATE TABLE IF NOT EXISTS `tbl_entries_data_".$this->get('id')."` ( + `id` int(11) unsigned NOT NULL auto_increment, + `entry_id` int(11) unsigned NOT NULL, + `value` int(11) default NULL, + PRIMARY KEY (`id`), + KEY `entry_id` (`entry_id`), + KEY `value` (`value`) + ) TYPE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;" + ); + } + + function isSortable() + { + return true; + } + + function canFilter() + { + return true; + } + + function allowDatasourceParamOutput() + { + return true; + } + + function canPrePopulate() + { + return true; + } + + function canToggle() + { + return false; + } + + /*------------------------------------------------------------------------- + SETTINGS + -------------------------------------------------------------------------*/ + + /** + * + * display settings panel + * + * @since version 1.0.0 + */ + + public function displaySettingsPanel(XMLElement &$wrapper, $errors = NULL) + { + parent::displaySettingsPanel($wrapper, $errors); + + // input "start number" + + $label = Widget::Label(__('Start Number (Must be a natural number)')); + $label->appendChild(WIDGET::Input('fields['.$this->get('sortorder').'][start_number]', $this->get('start_number'))); + if (isset($errors['start_number'])) { + $wrapper->appendChild(Widget::Error($label, $errors['start_number'])); + } else { + $wrapper->appendChild($label); + } + + $this->appendShowColumnCheckbox($wrapper); + } + + /** + * + * check fields + * + * validate the fields settings and return errors if wrong or missing input is detected + * + * @since version 1.2.0 + */ + + public function checkFields(Array &$errors, $checkForDuplicates = true) + { + // check if general field data is missing (label, handle) + + $parent = parent::checkFields($errors, $checkForDuplicates); + if ($parent != self::__OK__) return $parent; + + // build array of input data that needs to be validated by the extension + + $check = array(); + $check['start_number'] = $this->get('start_number'); + + // validate start number (must be a natural number) + + if(!preg_match('/^[0-9]+$/', $check['start_number'])) { + $errors['start_number'] = __('Start Number must be a natural number. e.g. 0 or 1'); + } + + return (!empty($errors) ? self::__ERROR__ : self::__OK__); + } + + /** + * + * commit field settings + * + * @since version 1.0.0 + */ + + public function commit() + { + if( !parent::commit() ) return false; + + $id = $this->get('id'); + if( $id === false ) return false; + + $fields = array(); + $fields['field_id'] = $id; + $fields['start_number'] = $this->get('start_number'); + + Symphony::Database()->query("DELETE FROM `tbl_fields_".$this->handle()."` WHERE `field_id` = '$id' LIMIT 1"); + + return Symphony::Database()->insert($fields, 'tbl_fields_'.$this->handle()); + } + + /*------------------------------------------------------------------------- + UI + -------------------------------------------------------------------------*/ + + /** + * + * prepare table value + * + * @since version 1.0.0 + */ + + public function displayPublishPanel(XMLElement &$wrapper, $data = NULL, $flagWithError = NULL, $fieldnamePrefix = NULL, $fieldnamePostfix = NULL, $entry_id = NULL) + { + $value = $data['value']; + $label = Widget::Label($this->get('label')); + + $label->appendChild( + Widget::Input( + 'fields'.$fieldnamePrefix.'['.$this->get('element_name').']'.$fieldnamePostfix, + (string) (strlen($value) != 0 ? $value : $this->getNewNumber()), + 'text', + array('readonly' => 'readonly') + ) + ); + + if( $flagWithError != NULL ) { + $wrapper->appendChild(Widget::Error($label, $flagWithError)); + } else { + $wrapper->appendChild($label); + } + } + + /** + * + * display datasource filter panel + * + * @since version 1.0.0 + */ + + public function displayDatasourceFilterPanel(XMLElement &$wrapper, $data = NULL, $errors = NULL, $fieldnamePrefix = NULL, $fieldnamePostfix = NULL) + { + $wrapper->appendChild(new XMLElement('h4', $this->get('label').' '.$this->Name().'')); + $label = Widget::Label('Value'); + $label->appendChild( + Widget::Input( + 'fields[filter]'.($fieldnamePrefix ? '['.$fieldnamePrefix.']' : '').'['.$this->get('id').']'.($fieldnamePostfix ? '['.$fieldnamePostfix.']' : ''), + ($data ? General::sanitize($data) : NULL)) + ); + $wrapper->appendChild($label); + + $wrapper->appendChild(new XMLElement('p', 'To filter by ranges, add mysql: to the beginning of the filter input. Use value for field name. E.G. mysql: value >= 1.01 AND value <= {$price}', array('class' => 'help'))); + } + + /*------------------------------------------------------------------------- + INPUT / SAVE FIELD DATA + -------------------------------------------------------------------------*/ + + /** + * + * check post field data + * + * @since version 1.0.0 + */ + + public function checkPostFieldData($data, &$message, $entry_id = NULL) + { + $message = NULL; + + if( $this->get('required') == 'yes' && strlen($data) == 0 ){ + $message = 'This is a required field.'; + return self::__MISSING_FIELDS__; + } + + if( strlen($data) > 0 && !is_numeric($data) ){ + $message = 'Must be a number.'; + return self::__INVALID_FIELDS__; + } + + return self::__OK__; + } + + /** + * + * process raw field data + * + * @since version 1.0.0 + */ + + public function processRawFieldData($data, &$status, &$message = NULL, $simulate = false, $entry_id = null) + { + if( !$data ) $data = $this->getNewNumber(); + + return parent::processRawFieldData($data, $status, $message, $simulate, $entry_id); + } + + /** + * + * get new number + * + * @since version 1.0.0 + */ + + public function getNewNumber() + { + $last_num = Symphony::Database()->fetch(" + SELECT `value` + FROM `tbl_entries_data_".$this->get('id')."` + ORDER BY `value` DESC LIMIT 1 + "); + + return (int) (!empty($last_num)) ? $last_num[0]['value'] + 1 : $this->get('start_number'); + } + + /*------------------------------------------------------------------------- + DATA SOURCE OUTPUT + -------------------------------------------------------------------------*/ + + /** + * + * build ds retrieval sql + * + * @since version 1.0.0 + */ + + function buildDSRetrievalSQL($data, &$joins, &$where, $andOperation = false) + { + if( preg_match('/^mysql:/i', $data[0]) ){ + + $field_id = $this->get('id'); + + $expression = str_replace(array('mysql:', 'value'), array('', " `t$field_id`.`value` "), $data[0]); + + $joins .= " LEFT JOIN `tbl_entries_data_$field_id` AS `t$field_id` ON (`e`.`id` = `t$field_id`.entry_id) "; + $where .= " AND $expression "; + } + + else parent::buildDSRetrievalSQL($data, $joins, $where, $andOperation); + + return true; + } +} From 0320ab96bf00cb2c3b754ce233b0066d5629f9ee Mon Sep 17 00:00:00 2001 From: Roman Klein Date: Mon, 29 Jan 2018 18:51:14 +0100 Subject: [PATCH 2/4] Fix license data --- LICENCE | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) mode change 100755 => 100644 LICENCE diff --git a/LICENCE b/LICENCE old mode 100755 new mode 100644 index f0c38cf..6422d89 --- a/LICENCE +++ b/LICENCE @@ -1,9 +1,9 @@ -All source code included in the "Field: Number" Symphony Extension archive -is, unless otherwise specified, released under the MIT licence as follows: +All source code included in the "Incremental Number Field" archive is, +unless otherwise specified, released under the MIT licence as follows: ----- begin license block ----- -Copyright 2008 Alistair Kearney, Allen Chang, Scott Hughes +Copyright 2011–2018 John Porter Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal From 72ce51999a3cffae83de18539c03213defd79aa1 Mon Sep 17 00:00:00 2001 From: Roman Klein Date: Mon, 29 Jan 2018 18:52:52 +0100 Subject: [PATCH 3/4] Improved Readme --- README.markdown | 15 --------------- README.md | 16 ++++++++++++++++ 2 files changed, 16 insertions(+), 15 deletions(-) delete mode 100644 README.markdown create mode 100644 README.md diff --git a/README.markdown b/README.markdown deleted file mode 100644 index be34098..0000000 --- a/README.markdown +++ /dev/null @@ -1,15 +0,0 @@ -Incremental Number Field -====================== - -## 1 About ## - -A field that automatically increments it's value by one for each new entry. - - -## 1 Installation ## - -1. Upload the 'incremental_number' folder in this archive to your Symphony 'extensions' folder. - -2. Enable it by selecting the "Field: Incremental Number", choose Enable from the with-selected menu, then click Apply. - -3. You can now add the "Incremental Number" field to your sections. diff --git a/README.md b/README.md new file mode 100644 index 0000000..fe38566 --- /dev/null +++ b/README.md @@ -0,0 +1,16 @@ +# Incremental Number Field + +A field that automatically increments it's value by one for each new entry in a section. + +## 1. Installation + +1. Upload the `/incremental_number` folder in this archive to your Symphony `/extensions` folder. +2. Go to '**System → Extensions**' in your Symphony admin area. +3. Enable the extension by selecting '**Field: Incremental Number**', choose '**Enable**' from the '**With Selected…**' menu, then click '**Apply**'. + +## 2. Usage + +1. Add the field type '**Incremental Number**' to a section of your choice. +2. Define a valid '**Start Number**' for the field (has to be a natural number, e.g. `0` or `1`). +3. Now each time you create an entry in this section the '**Incremental Number**'-field will automatically get populated by fetching the '**Incremental Number**'-value of the previous entry and incrementing it by 1. If there is no previous entry in the section the field will instead get populated with the given '**Start Number**'. +4. You can't manually edit the values of an '**Incremental Number Field**' – they're read-only. From 915618b92f62e01956ef58fcfba297bace40d4b5 Mon Sep 17 00:00:00 2001 From: Roman Klein Date: Mon, 29 Jan 2018 18:54:24 +0100 Subject: [PATCH 4/4] Release 1.2.0 - Added 1.2.0 release data - Fixed compatibility data for releases 1.0.0 and 1.1.0 - Fixed broken links --- extension.meta.xml | 39 ++++++++++++++++++++------------------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/extension.meta.xml b/extension.meta.xml index 0b47653..64915de 100644 --- a/extension.meta.xml +++ b/extension.meta.xml @@ -1,35 +1,36 @@ - + Incremental Number Field - - Increment a number per entry in a section - + A field that automatically increments it's value by one for each new entry in a section. https://github.com/designermonkey/incremental_number - - http://symphony-cms.com/discuss/thread/81151/ - + https://github.com/designermonkey/incremental_number/issues + http://www.getsymphony.com/discuss/thread/81151/ - Field Types + Field - John Porter http://designermonkey.co.uk - Vlad Ghita - vlad_micutul@yahoo.com - http://www.xanderadvertising.com + Roman Klein + https://github.com/twiro - - - - + + - Code cleanup & reformatting + - Improved Readme & fixed Meta + - PHP 7.0 compatibility + - Symphony 2.6 & 2.7 compatibility [#8](https://github.com/designermonkey/incremental_number/issues/8) + - Added field settings validation [#9](https://github.com/designermonkey/incremental_number/issues/9) + + + - Cleanup & Symphony 2.3 compatibility. + + + - Initial release + -