From 3db78b328f9c1d35d382843e7274d9eebb6fcc6a Mon Sep 17 00:00:00 2001 From: Manoj L Date: Thu, 3 Jan 2019 15:55:59 +0530 Subject: [PATCH 1/2] Issue #89 feat: Category plugin enhancements - Update get single category api - Update get category list api --- categories/README.md | 80 +++++++----- categories/categories.php | 35 +++-- categories/categories.xml | 17 ++- categories/categories/categories.php | 185 ++++++++++----------------- categories/categories/category.php | 160 +++++++++++++++++++++++ 5 files changed, 307 insertions(+), 170 deletions(-) create mode 100644 categories/categories/category.php diff --git a/categories/README.md b/categories/README.md index 1b19e1a..012d355 100644 --- a/categories/README.md +++ b/categories/README.md @@ -1,51 +1,57 @@ API to create and get Joomla categories -## Create / Update Category +## Get Single Category ```http -POST /index.php?option=com_api&app=categories&resource=categories&format=raw +GET /index.php?option=com_api&app=categories&resource=category&format=raw&id=:id ``` -OR update an existing category + +Alternatively, you can call this API as follow (assuming you have created a menu with alias as 'api' for com_api) + ```http -POST /index.php?option=com_api&app=categories&resource=categories&format=raw&id=:id +GET /api/categories/category/:id ``` #### Request Params -| Param Name | Required | Type | Comment | -| ---------- | -------- | ------- | :---- | -| title | YES | STRING | | -| alias | NO | STRING | URL alias. Will be generated based on title if kept empty | -| description | NO | STRING | | -| published | NO | INT | 1 = Published (Default) / 0 = Unpublished | -| parent_id | NO | INT | Specify a parent category id if you wish to create a subcategory | -| language | NO | STRING | Will use the site's default language if none provided. | -| extension | YES | STRING | Since Joomla supports using the categories extension for 3rd party components, this field specifies the extension name. Use com_content for article categories. | -| access | NO | INT | Access Level for Category | +| Param Name | Required | Comment | +| ---------- | -------- | :------ | +| fields | NO | Defaults to id, title, created_time | #### Response Params -| Param Name | Comment | -| ---------- | :------ | -| success | true if the category was created, false if there was a problem | +| Param Name | Comment | +| ---------- | :------- | +| success | true if the API call succeeds, false if there was a problem | | message | Error mesage in case success is false | | data.results | Array containing a single [Category Object](#category-object) in case of success. Empty array in case of failure. | ## Get Categories List + ```http GET /index.php?option=com_api&app=categories&resource=categories&format=raw ``` + +Alternatively, you can call this API as follow (assuming you have created a menu with alias as 'api' for com_api) + +```http +GET /api/categories/categories +``` + #### Request Params | Param Name | Required | Comment | | ---------- | -------- | :------ | -| limit | NO | Defaults to 20 | -| limitstart | NO | Defaults to 0 | -| filters | NO | Key value pairs of values to filter on | -| search | NO | search key for searching category titles | -| fields | NO | Defaults to id, title, created_time | - +| limit | NO | Defaults to 20 | +| limitstart | NO | Defaults to 0 | +| search | NO | search key for searching category titles | +| filters[access] | NO | Access level | +| filters[extension] | NO | Defaults to 'com_content' | +| filters[language] | NO | eg: hi-IN for Hindi | +| filters[level] | NO | eg: 1 for top level | +| filters[published] | NO | 1 / 0, defaults to 1 | +| fields (not implemented yet) | NO | Defaults to id, title, created_time | #### Response Params @@ -55,28 +61,38 @@ GET /index.php?option=com_api&app=categories&resource=categories&format=raw | message | Error mesage in case success is false | | data.results | Array of [Category Objects](#category-object) in case of success. Empty array in case of failure. | +## Create / Update Category -## Get Single Category ```http -GET /index.php?option=com_api&app=categories&resource=categories&format=raw&id=:id +POST /index.php?option=com_api&app=categories&resource=categories&format=raw +``` +OR update an existing category +```http +POST /index.php?option=com_api&app=categories&resource=categories&format=raw&id=:id ``` #### Request Params -| Param Name | Required | Comment | -| ---------- | -------- | :------ | -| fields | NO | Defaults to id, title, created_time | +| Param Name | Required | Type | Comment | +| ---------- | -------- | ------- | :---- | +| title | YES | STRING | | +| alias | NO | STRING | URL alias. Will be generated based on title if kept empty | +| description | NO | STRING | | +| published | NO | INT | 1 = Published (Default) / 0 = Unpublished | +| parent_id | NO | INT | Specify a parent category id if you wish to create a subcategory | +| language | NO | STRING | Will use the site's default language if none provided. | +| extension | YES | STRING | Since Joomla supports using the categories extension for 3rd party components, this field specifies the extension name. Use com_content for article categories. | +| access | NO | INT | Access Level for Category | #### Response Params -| Param Name | Comment | -| ---------- | :------- | -| success | true if the API call succeeds, false if there was a problem | +| Param Name | Comment | +| ---------- | :------ | +| success | true if the category was created, false if there was a problem | | message | Error mesage in case success is false | | data.results | Array containing a single [Category Object](#category-object) in case of success. Empty array in case of failure. | - ## Category Object The actual contents of the category object will vary based on which fields are requested, however the below is the list of all possible fields. diff --git a/categories/categories.php b/categories/categories.php index ac3ccca..8757234 100644 --- a/categories/categories.php +++ b/categories/categories.php @@ -1,21 +1,36 @@ - * @link http://www.techjoomla.com -*/ + * @package API + * @subpackage com_api + * + * @author Techjoomla + * @copyright Copyright (C) 2009 - 2019 Techjoomla, Tekdi Technologies Pvt. Ltd. All rights reserved. + * @license GNU GPLv2 + */ -defined('_JEXEC') or die( 'Restricted access' ); +// No direct access. +defined('_JEXEC') or die('Restricted access'); -jimport('joomla.plugin.plugin'); - -class plgAPICategories extends ApiPlugin +/** + * Category API plugin class + * + * @package API + * @since 1.6.0 + */ +class PlgAPICategories extends ApiPlugin { + /** + * Constructor. + * + * @param object &$subject The object to observe. + * @param array $config An optional associative array of configuration settings. + * + * @since 1.6.0 + */ public function __construct(&$subject, $config = array()) { parent::__construct($subject, $config = array()); - ApiResource::addIncludePath(dirname(__FILE__).'/categories'); + ApiResource::addIncludePath(dirname(__FILE__) . '/categories'); } } diff --git a/categories/categories.xml b/categories/categories.xml index 8408abe..3eec4d9 100644 --- a/categories/categories.xml +++ b/categories/categories.xml @@ -9,18 +9,17 @@ Techjoomla. All rights reserved. http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL This plugin is for content Request - - categories.php + + categories.php categories - - - en-GB.plg_api_categories.ini - en-GB.plg_api_categories.sys.ini - + + + en-GB.plg_api_categories.ini + en-GB.plg_api_categories.sys.ini + -
-
+
diff --git a/categories/categories/categories.php b/categories/categories/categories.php index cb9a88f..58e1e7f 100644 --- a/categories/categories/categories.php +++ b/categories/categories/categories.php @@ -1,138 +1,85 @@ - * @link http://www.techjoomla.com + * @package API + * @subpackage com_api + * + * @author Techjoomla + * @copyright Copyright (C) 2009 - 2019 Techjoomla, Tekdi Technologies Pvt. Ltd. All rights reserved. + * @license GNU GPLv2 */ -defined('_JEXEC') or die( 'Restricted access' ); -require_once JPATH_ADMINISTRATOR . '/components/com_categories/models/categories.php'; -jimport('joomla.plugin.plugin'); -jimport('joomla.html.html'); -JLoader::register('JCategoryNode', JPATH_BASE . '/libraries/legacy/categories/categories.php'); +// No direct access. +defined('_JEXEC') or die('Restricted access'); +// Load category list model from admin +JLoader::register('CategoriesModelCategories', JPATH_ROOT . '/administrator/components/com_categories/models/categories.php'); +/** + * Categories API resource class + * + * @package API + * @since 1.6.0 + */ class CategoriesApiResourceCategories extends ApiResource { - public function get() - { - $this->plugin->setResponse($this->getCategoryList()); - } - - public function delete() - { - $this->plugin->setResponse('in delete'); - } - public function post() - { - $this->plugin->setResponse($this->CreateUpdateCategory()); - } - - public function getCategory() - { - self::getListQuery(); - } - - /** - * Get the master query for retrieving a list of categories subject to the model state. - * - * @return JDatabaseQuery + /** + * Get categories * - * @since 1.6 + * @return obj Categories list wrapped inside standard api response wrapper */ - public function getCategoryList() + public function get() { - /*$model_categories = JCategories::getInstance('Content'); - $root = $model_categories->get('root'); - $categories = $root->getChildren();*/ - - $model_categories = JCategories::getInstance('Content'); - $root = $model_categories->get('root'); - $categories = $root->getChildren(true); - - return $categories; - + $this->plugin->setResponse($this->getCategoriesList()); } + /** - * CreateUpdateCategory is to create / upadte Category + * Get list of categories based on input params * - * @return Bolean + * @return array * - * @since 3.5 + * @since 1.6.0 */ - public function CreateUpdateCategory() + public function getCategoriesList() { - if (version_compare(JVERSION, '3.0', 'lt')) - { - JTable::addIncludePath(JPATH_PLATFORM . 'joomla/database/table'); - } - - $obj = new stdclass; - - $app = JFactory::getApplication(); - $cat_id = $app->input->get('id', 0, 'INT'); - - if (empty($app->input->get('title', '', 'STRING'))) - { - $obj->code = 'ER001'; - $obj->message = 'Title Field is Missing'; - - return $obj; - } - if (empty($app->input->get('extension', '', 'STRING'))) - { - $obj->code = 'ER002'; - $obj->message = 'Extension Field is Missing'; - - return $obj; - } - - - if ($cat_id) - { - $category = JTable::getInstance('Content', 'JTable', array()); - $category->load($cat_id); - $data = array( - 'title' => $app->input->get('title', '', 'STRING'), - ); - - // Bind data - if (!$cat_id->bind($data)) - { - $this->setError($article->getError()); - return false; - } - } - else - { - $category = JTable::getInstance('content'); - $category->title = $app->input->get('title', '', 'STRING'); - $category->alias = $app->input->get('alias', '', 'STRING'); - $category->description = $app->input->get('description', '', 'STRING'); - $category->published = $app->input->get('published', '', 'STRING'); - $category->parent_id = $app->input->get('parent_id', '', 'STRING'); - $category->extension = $app->input->get('language', '', 'INT'); - $category->access = $app->input->get('catid', '', 'INT'); - } - - // Check the data. - if (!$category->check()) - { - $this->setError($category->getError()); - - return false; - } - - // Store the data. - if (!$category->store()) - { - $this->setError($category->getError()); - - return false; - } - - //return true; + // Get an instance of the generic articles model + $model = JModelLegacy::getInstance('Categories', 'CategoriesModel', array('ignore_request' => true)); + + // Set application parameters in model + $app = JFactory::getApplication(); + $input = $app->input; + + // Get inputs params + $limit = $input->get->get('limit', 20, 'int'); + $limitStart = $input->get->get('limitstart', 0, 'int'); + $search = $input->get->get('search', '', 'string'); + + // Get filters + $filters = $input->get->get('filters', '', 'array'); + $jInputFilter = JFilterInput::getInstance(); + + // Cleanup and set default values + $access = isset($filters['access']) ? $jInputFilter->clean($filters['access'], 'cmd') : ''; + $extension = isset($filters['extension']) ? $jInputFilter->clean($filters['extension'], 'cmd') : 'com_content'; + $language = isset($filters['language']) ? $jInputFilter->clean($filters['language'], 'string') : ''; + $level = isset($filters['level']) ? $jInputFilter->clean($filters['level'], 'string') : ''; + $published = isset($filters['published']) ? $jInputFilter->clean($filters['published'], 'int') : 1; + + // Set the filters based on the module params + $model->setState('list.limit', $limit); + $model->setState('list.start', $limitStart); + $model->setState('filter.search', $search); + + $model->setState('filter.access', $access); + $model->setState('filter.extension', $extension); + $model->setState('filter.language', $language); + $model->setState('filter.level', $level); + $model->setState('filter.published', $published); + + // Extract the component name, Extract the optional section name + $parts = explode('.', $extension); + $model->setState('filter.component', $parts[0]); + $model->setState('filter.section', (count($parts) > 1) ? $parts[1] : null); + + return $model->getItems(); } - } diff --git a/categories/categories/category.php b/categories/categories/category.php new file mode 100644 index 0000000..fc24bfe --- /dev/null +++ b/categories/categories/category.php @@ -0,0 +1,160 @@ + + * @copyright Copyright (C) 2009 - 2019 Techjoomla, Tekdi Technologies Pvt. Ltd. All rights reserved. + * @license GNU GPLv2 + */ + +// No direct access. +defined('_JEXEC') or die('Restricted access'); + +JLoader::register('CategoriesModelCategory', JPATH_ROOT . '/administrator/components/com_categories/models/category.php'); + +/** + * Category API resource class + * + * @package API + * @since 1.6.0 + */ +class CategoriesApiResourceCategory extends ApiResource +{ + /** + * Get categories + * + * @return obj Category details wrapped inside standard api response wrapper + */ + public function get() + { + $this->plugin->setResponse($this->getCategory()); + } + + /** + * Save category - create / update + * + * @return obj Category details wrapped inside standard api response wrapper + */ + public function post() + { + // $this->plugin->setResponse($this->saveCategory()); + } + + /** + * Get category details + * + * @return array + * + * @since 1.6.0 + */ + public function getCategory() + { + // 1. Important to include category table first + JTable::addIncludePath(JPATH_ROOT . '/administrator/components/com_categories/tables'); + + // 2. Then, get an instance of the generic articles model + $model = JModelLegacy::getInstance('Category', 'CategoriesModel', array('ignore_request' => true)); + + // Set application parameters in model + $app = JFactory::getApplication(); + $input = $app->input; + + // Important to get from input directly and not from $input->get->get() + $id = $input->get('id', 0, 'int'); + + if (!$id) + { + // Not Found Error sets HTTP 404 + ApiError::raiseError(404, "Record not found", 'APINotFoundException'); + } + + $item = $model->getItem($id); + + // Exists? + if (empty($item->id)) + { + // Not Found Error sets HTTP 404 + ApiError::raiseError(404, "Record not found", 'APINotFoundException'); + } + + return $item; + } + + /** + * CreateUpdateCategory is to create / upadte Category + * + * @return Bolean + * + * @since 3.5 + */ + /*public function saveCategory() + { + if (version_compare(JVERSION, '3.0', 'lt')) + { + JTable::addIncludePath(JPATH_PLATFORM . 'joomla/database/table'); + } + + $obj = new stdclass; + + $app = JFactory::getApplication(); + $cat_id = $app->input->post->get('id', 0, 'INT'); + + if (empty($app->input->post->get('title', '', 'STRING'))) + { + $obj->code = 'ER001'; + $obj->message = 'Title Field is Missing'; + + return $obj; + } + + if (empty($app->input->post->get('extension', '', 'STRING'))) + { + $obj->code = 'ER002'; + $obj->message = 'Extension Field is Missing'; + + return $obj; + } + + if ($cat_id) + { + $category = JTable::getInstance('Content', 'JTable', array()); + $category->load($cat_id); + $data = array( + 'title' => $app->input->post->get('title', '', 'STRING'), + ); + + if (!$cat_id->bind($data)) + { + $this->setError($article->getError()); + + return false; + } + } + else + { + $category = JTable::getInstance('content'); + $category->title = $app->input->post->get('title', '', 'STRING'); + $category->alias = $app->input->post->get('alias', '', 'STRING'); + $category->description = $app->input->post->get('description', '', 'STRING'); + $category->published = $app->input->post->get('published', '', 'STRING'); + $category->parent_id = $app->input->post->get('parent_id', '', 'STRING'); + $category->extension = $app->input->post->get('language', '', 'INT'); + $category->access = $app->input->post->get('catid', '', 'INT'); + } + + if (!$category->check()) + { + $this->setError($category->getError()); + + return false; + } + + if (!$category->store()) + { + $this->setError($category->getError()); + + return false; + } + }*/ +} From bfef900c05683c7a74cfce1f3ba38f401a0df160 Mon Sep 17 00:00:00 2001 From: Manoj L Date: Thu, 3 Jan 2019 16:24:40 +0530 Subject: [PATCH 2/2] Issue #89 feat: Fix return types --- categories/categories/categories.php | 2 +- categories/categories/category.php | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/categories/categories/categories.php b/categories/categories/categories.php index 58e1e7f..5bbedc3 100644 --- a/categories/categories/categories.php +++ b/categories/categories/categories.php @@ -25,7 +25,7 @@ class CategoriesApiResourceCategories extends ApiResource /** * Get categories * - * @return obj Categories list wrapped inside standard api response wrapper + * @return object Categories list wrapped inside standard api response wrapper */ public function get() { diff --git a/categories/categories/category.php b/categories/categories/category.php index fc24bfe..49a9be1 100644 --- a/categories/categories/category.php +++ b/categories/categories/category.php @@ -24,7 +24,7 @@ class CategoriesApiResourceCategory extends ApiResource /** * Get categories * - * @return obj Category details wrapped inside standard api response wrapper + * @return object Category details wrapped inside standard api response wrapper */ public function get() { @@ -34,7 +34,7 @@ public function get() /** * Save category - create / update * - * @return obj Category details wrapped inside standard api response wrapper + * @return object Category details wrapped inside standard api response wrapper */ public function post() {