diff --git a/administrator/components/com_categories/helpers/categories.php b/administrator/components/com_categories/helpers/categories.php index 4e4d603c3411e..5f263761acf6c 100644 --- a/administrator/components/com_categories/helpers/categories.php +++ b/administrator/components/com_categories/helpers/categories.php @@ -137,4 +137,50 @@ public static function getAssociations($pk, $extension = 'com_content') return $associations; } + + /** + * Check if Category ID exists otherwise assign to ROOT category. + * + * @param mixed $catid Name or ID of category. + * @param string $extension Extension that triggers this function + * + * @return int $catid Category ID. + */ + public static function validateCategoryId($catid, $extension) + { + JTable::addIncludePath(JPATH_ADMINISTRATOR . '/components/com_categories/tables'); + + $categoryTable = JTable::getInstance('Category'); + + $data = array(); + $data['id'] = $catid; + $data['extension'] = $extension; + + if (!$categoryTable->load($data)) + { + $catid = 0; + } + + return (int) $catid; + } + + /** + * Create new Category from within item view. + * + * @param array $data Array of data for new category. + * + * @return integer. + */ + public static function createCategory($data) + { + JModelLegacy::addIncludePath(JPATH_ADMINISTRATOR . '/components/com_categories/models'); + JTable::addIncludePath(JPATH_ADMINISTRATOR . '/components/com_categories/tables'); + + $categoryModel = JModelLegacy::getInstance('Category', 'CategoriesModel'); + $categoryModel->save($data); + + $catid = $categoryModel->getState('category.id'); + + return $catid; + } } diff --git a/administrator/components/com_categories/models/fields/categoryedit.php b/administrator/components/com_categories/models/fields/categoryedit.php index cf6f558a9d493..01db332a5a6dd 100644 --- a/administrator/components/com_categories/models/fields/categoryedit.php +++ b/administrator/components/com_categories/models/fields/categoryedit.php @@ -20,6 +20,14 @@ */ class JFormFieldCategoryEdit extends JFormFieldList { + /** + * To allow creation of new categories. + * + * @var int + * @since 3.6 + */ + protected $allowAdd; + /** * A flexible category list that respects access controls * @@ -28,6 +36,77 @@ class JFormFieldCategoryEdit extends JFormFieldList */ public $type = 'CategoryEdit'; + /** + * Method to attach a JForm object to the field. + * + * @param SimpleXMLElement $element The SimpleXMLElement object representing the tag for the form field object. + * @param mixed $value The form field value to validate. + * @param string $group The field name group control value. This acts as as an array container for the field. + * For example if the field has name="foo" and the group value is set to "bar" then the + * full field name would end up being "bar[foo]". + * + * @return boolean True on success. + * + * @see JFormField::setup() + * @since 3.2 + */ + public function setup(SimpleXMLElement $element, $value, $group = null) + { + $return = parent::setup($element, $value, $group); + + if ($return) + { + $this->allowAdd = isset($this->element['allowAdd']) ? $this->element['allowAdd'] : ''; + } + + return $return; + } + + /** + * Method to get certain otherwise inaccessible properties from the form field object. + * + * @param string $name The property name for which to the the value. + * + * @return mixed The property value or null. + * + * @since 3.6 + */ + public function __get($name) + { + switch ($name) + { + case 'allowAdd': + return $this->$name; + } + + return parent::__get($name); + } + + /** + * Method to set certain otherwise inaccessible properties of the form field object. + * + * @param string $name The property name for which to the the value. + * @param mixed $value The value of the property. + * + * @return void + * + * @since 3.6 + */ + public function __set($name, $value) + { + $value = (string) $value; + + switch ($name) + { + case 'allowAdd': + $value = (string) $value; + $this->$name = ($value === 'true' || $value === $name || $value === '1'); + break; + default: + parent::__set($name, $value); + } + } + /** * Method to get a list of categories that respects access controls and can be used for * either category assignment or parent category assignment in edit screens. @@ -229,4 +308,85 @@ protected function getOptions() // Merge any additional options in the XML definition. return array_merge(parent::getOptions(), $options); } + + /** + * Method to get the field input markup for a generic list. + * Use the multiple attribute to enable multiselect. + * + * @return string The field input markup. + * + * @since 3.6 + */ + protected function getInput() + { + $html = array(); + $class = array(); + $attr = ''; + + // Initialize some field attributes. + $class[] = !empty($this->class) ? $this->class : ''; + + if ($this->allowAdd) + { + $customGroupText = JText::_('JGLOBAL_CUSTOM_CATEGORY'); + + $class[] = 'chzn-custom-value'; + $attr .= ' data-custom_group_text="' . $customGroupText . '" ' + . 'data-no_results_text="' . JText::_('JGLOBAL_ADD_CUSTOM_CATEGORY') . '" ' + . 'data-placeholder="' . JText::_('JGLOBAL_TYPE_OR_SELECT_CATEGORY') . '" '; + } + + if ($class) + { + $attr .= 'class="' . implode(' ', $class) . '"'; + } + + $attr .= !empty($this->size) ? ' size="' . $this->size . '"' : ''; + $attr .= $this->multiple ? ' multiple' : ''; + $attr .= $this->required ? ' required aria-required="true"' : ''; + $attr .= $this->autofocus ? ' autofocus' : ''; + + // To avoid user's confusion, readonly="true" should imply disabled="true". + if ((string) $this->readonly == '1' || (string) $this->readonly == 'true' || (string) $this->disabled == '1'|| (string) $this->disabled == 'true') + { + $attr .= ' disabled="disabled"'; + } + + // Initialize JavaScript field attributes. + $attr .= $this->onchange ? ' onchange="' . $this->onchange . '"' : ''; + + // Get the field options. + $options = (array) $this->getOptions(); + + // Create a read-only list (no name) with hidden input(s) to store the value(s). + if ((string) $this->readonly == '1' || (string) $this->readonly == 'true') + { + $html[] = JHtml::_('select.genericlist', $options, '', trim($attr), 'value', 'text', $this->value, $this->id); + + // E.g. form field type tag sends $this->value as array + if ($this->multiple && is_array($this->value)) + { + if (!count($this->value)) + { + $this->value[] = ''; + } + + foreach ($this->value as $value) + { + $html[] = ''; + } + } + else + { + $html[] = ''; + } + } + else + // Create a regular list. + { + $html[] = JHtml::_('select.genericlist', $options, $this->name, trim($attr), 'value', 'text', $this->value, $this->id); + } + + return implode($html); + } } diff --git a/administrator/components/com_content/models/article.php b/administrator/components/com_content/models/article.php index 75e401854f7ae..43589296b8507 100644 --- a/administrator/components/com_content/models/article.php +++ b/administrator/components/com_content/models/article.php @@ -487,6 +487,31 @@ public function save($data) $data['images'] = (string) $registry; } + JLoader::register('CategoriesHelper', JPATH_ADMINISTRATOR . '/components/com_categories/helpers/categories.php'); + + // Cast catid to integer for comparison + $catid = (int) $data['catid']; + + // Check if New Category exists + if ($catid > 0) + { + $catid = CategoriesHelper::validateCategoryId($data['catid'], 'com_content'); + } + + // Save New Category + if ($catid == 0) + { + $table = array(); + $table['title'] = $data['catid']; + $table['parent_id'] = 1; + $table['extension'] = 'com_content'; + $table['language'] = $data['language']; + $table['published'] = 1; + + // Create new category and get catid back + $data['catid'] = CategoriesHelper::createCategory($table); + } + if (isset($data['urls']) && is_array($data['urls'])) { $check = $input->post->get('jform', array(), 'array'); diff --git a/administrator/components/com_content/models/forms/article.xml b/administrator/components/com_content/models/forms/article.xml index 1ed973d17fd30..056ec2d6739b9 100644 --- a/administrator/components/com_content/models/forms/article.xml +++ b/administrator/components/com_content/models/forms/article.xml @@ -42,9 +42,13 @@ JTRASHED - diff --git a/administrator/components/com_content/views/article/tmpl/edit.php b/administrator/components/com_content/views/article/tmpl/edit.php index ef414b960983d..a4d57b4df4e33 100644 --- a/administrator/components/com_content/views/article/tmpl/edit.php +++ b/administrator/components/com_content/views/article/tmpl/edit.php @@ -14,7 +14,7 @@ JHtml::_('behavior.formvalidator'); JHtml::_('behavior.keepalive'); -JHtml::_('formbehavior.chosen', 'select'); +JHtml::_('formbehavior.chosen', 'select', null, array('disable_search_threshold' => 0 )); $this->configFieldsets = array('editorConfig'); $this->hiddenFieldsets = array('basic-limited'); diff --git a/administrator/language/en-GB/en-GB.ini b/administrator/language/en-GB/en-GB.ini index 49c527a4c3005..9322082cf59b4 100644 --- a/administrator/language/en-GB/en-GB.ini +++ b/administrator/language/en-GB/en-GB.ini @@ -187,7 +187,7 @@ JFIELD_BASIS_LOGOUT_DESCRIPTION_DESC="Text for logout page." JFIELD_BASIS_LOGOUT_DESCRIPTION_LABEL="Logout Description Text" JFIELD_BASIS_LOGOUT_DESCRIPTION_SHOW_DESC="Show or hide logout description." JFIELD_BASIS_LOGOUT_DESCRIPTION_SHOW_LABEL="Logout Text" -JFIELD_CATEGORY_DESC="The category that this item is assigned to." +JFIELD_CATEGORY_DESC="The category that this item is assigned to. You may select an existing category or enter a new category by typing the name in the field and pressing enter." JFIELD_ENABLED_DESC="The enabled status of this item." JFIELD_KEY_REFERENCE_DESC="Used to store information referring to an external resource." JFIELD_KEY_REFERENCE_LABEL="Key Reference" @@ -242,6 +242,7 @@ JFIELD_XREFERENCE_LABEL="External Reference" JGLOBAL_ACROSS="Across" JGLOBAL_ACTION_PERMISSIONS_LABEL="Permissions" JGLOBAL_ACTION_PERMISSIONS_DESCRIPTION="Set the action permissions for this asset" +JGLOBAL_ADD_CUSTOM_CATEGORY="Add new Category" JGLOBAL_ALL_ARTICLE="Max Levels Articles" JGLOBAL_ALL_LIST="Max Levels as List" JGLOBAL_ALLOW_COMMENTS_DESC="If Yes, viewers will be able to add and view comments for the article." @@ -301,6 +302,7 @@ JGLOBAL_CLICK_TO_TOGGLE_STATE="Select icon to toggle state." JGLOBAL_COPY="(copy)" JGLOBAL_CREATED="Created" JGLOBAL_CREATED_DATE="Created Date" +JGLOBAL_CUSTOM_CATEGORY="New Categories" JGLOBAL_DATE_FORMAT_DESC="Optional format string for showing the date. If left blank, it uses DATE_FORMAT_LC1 from your language file (for example, D M Y for day month year or you can use d-m-y for a short version eg. 10-07-10. See http://www.php.net/manual/en/function.date.php)." JGLOBAL_DATE_FORMAT_LABEL="Date Format" JGLOBAL_DESCRIPTION="Description" @@ -556,6 +558,7 @@ JGLOBAL_TITLE_REVERSE_ALPHABETICAL="Title Reverse Alphabetical" JGLOBAL_TOGGLE_FEATURED="Toggle featured status." JGLOBAL_TOP="Top" JGLOBAL_TPL_CPANEL_LINK_TEXT="Return to Control Panel" +JGLOBAL_TYPE_OR_SELECT_CATEGORY="Type or Select a Category" JGLOBAL_USE_GLOBAL="Use Global" JGLOBAL_USERNAME="Username" JGLOBAL_VALIDATION_FORM_FAILED="Invalid form" diff --git a/components/com_content/models/forms/article.xml b/components/com_content/models/forms/article.xml index 7b2a5808e6b60..3708ed76454e5 100644 --- a/components/com_content/models/forms/article.xml +++ b/components/com_content/models/forms/article.xml @@ -98,7 +98,8 @@ label="JCATEGORY" description="JFIELD_CATEGORY_DESC" class="inputbox" - required="true"> + required="true" + >