SproutCMS

This is the code documentation for the SproutCMS project

source of /sprout/Helpers/Category.php

  1. <?php
  2. /*
  3.  * Copyright (C) 2017 Karmabunny Pty Ltd.
  4.  *
  5.  * This file is a part of SproutCMS.
  6.  *
  7.  * SproutCMS is free software: you can redistribute it and/or modify it under the terms
  8.  * of the GNU General Public License as published by the Free Software Foundation, either
  9.  * version 2 of the License, or (at your option) any later version.
  10.  *
  11.  * For more information, visit <http://getsproutcms.com>.
  12.  */
  13.  
  14. namespace Sprout\Helpers;
  15.  
  16. use InvalidArgumentException;
  17.  
  18. use karmabunny\pdb\Exceptions\RowMissingException;
  19. use karmabunny\pdb\Exceptions\ConstraintQueryException;
  20.  
  21.  
  22. class Category
  23. {
  24.  
  25. /**
  26.   * Creates a category.
  27.   * Returns the id or NULL on failure.
  28.   *
  29.   * @param string $table The 'main' table (e.g. 'articles')
  30.   * @param string $name The name of the category to add
  31.   **/
  32. public static function create($table, $name)
  33. {
  34. $update_data = array();
  35. $update_data['name'] = $name;
  36. $update_data['date_added'] = Pdb::now();
  37. $update_data['date_modified'] = Pdb::now();
  38. return Pdb::insert(self::tableMain2cat($table), $update_data);
  39. }
  40.  
  41.  
  42. /**
  43.   * Looks up a category.
  44.   * Returns the id, or NULL if not found.
  45.   *
  46.   * @param string $table The 'main' table (e.g. 'articles')
  47.   * @param string $name The name of the category to find
  48.   * @param bool $case_sensitive True for a case sensitive match. Default false
  49.   **/
  50. public static function lookup($table, $name, $case_sensitive = false)
  51. {
  52. $table_cat = self::tableMain2cat($table);
  53.  
  54. $conditions = [];
  55. if ($case_sensitive) {
  56. $conditions[] = ['name', '=', $name];
  57.  
  58. } else {
  59. $conditions[] = ['name', 'CONTAINS', $name];
  60. }
  61.  
  62. $params = [];
  63. $where = Pdb::buildClause($conditions, $params);
  64. $q = "SELECT id FROM ~{$table_cat} WHERE {$where}";
  65. try {
  66. return Pdb::q($q, $params, 'val');
  67. } catch (RowMissingException $ex) {
  68. return null;
  69. }
  70. }
  71.  
  72.  
  73. /**
  74.   * Looks up a category. If not found, creates the category.
  75.   * Returns the id or NULL on failure.
  76.   *
  77.   * @param string $table The 'main' table (e.g. 'articles')
  78.   * @param string $name The name of the category to find or add
  79.   * @param bool $case_sensitive True for a case sensitive match. Default false
  80.   **/
  81. public static function lookupOrCreate($table, $name, $case_sensitive = false)
  82. {
  83. $id = self::lookup($table, $name, $case_sensitive);
  84.  
  85. if (! $id) {
  86. $id = self::create($table, $name);
  87. }
  88.  
  89. return $id;
  90. }
  91.  
  92.  
  93. /**
  94.   * Get the name of a category based on the category id
  95.   * Returns the name, or NULL if not found.
  96.   *
  97.   * @param string $table The 'main' table (e.g. 'articles')
  98.   * @param string $id The ID of the category to get the name of
  99.   * @param string The category name
  100.   **/
  101. public static function name($table, $id)
  102. {
  103. $id = (int) $id;
  104.  
  105. $table_cat = self::tableMain2cat($table);
  106.  
  107. $q = "SELECT name FROM ~{$table_cat} WHERE id = ?";
  108. try {
  109. return Pdb::q($q, [$id], 'val');
  110. } catch (RowMissingException $ex) {
  111. return null;
  112. }
  113. }
  114.  
  115.  
  116. /**
  117.   * Converts a main table name into a category table name.
  118.   * Assumes standard naming conventions.
  119.   * @throws InvalidArgumentException If the table name is not a valid identifier
  120.   * @param string $table Main table name, e.g. 'articles'
  121.   * @return string Category table name, e.g. 'articles_cat_list'
  122.   */
  123. public static function tableMain2cat($table)
  124. {
  125. Pdb::validateIdentifier($table); // if this is valid then return value will be
  126. return $table . '_cat_list';
  127. }
  128.  
  129.  
  130. /**
  131.   * Converts a main table name into a joiner table name.
  132.   * Assumes standard naming conventions.
  133.   * @throws InvalidArgumentException If the table name is not a valid identifier
  134.   * @param string $table Main table name, e.g. 'articles'
  135.   * @return string Joiner table name, e.g. 'articles_cat_join'
  136.   */
  137. public static function tableMain2joiner($table)
  138. {
  139. Pdb::validateIdentifier($table);
  140. return $table . '_cat_join';
  141. }
  142.  
  143.  
  144. /**
  145.   * Converts a main table name into a joiner column name.
  146.   * Assumes standard naming conventions.
  147.   * @throws InvalidArgumentException If the table name is not a valid identifier
  148.   * @param string $table Main table name, e.g. 'articles'
  149.   * @return string Joiner column name, e.g. 'article_id'
  150.   */
  151. public static function columnMain2joiner($table)
  152. {
  153. Pdb::validateIdentifier($table);
  154. return Inflector::singular($table) . '_id';
  155. }
  156.  
  157.  
  158. /**
  159.   * Converts a category table (e.g. 'articles_cat_list') into a main table (e.g. 'articles')
  160.   * Assumes standard naming conventions.
  161.   * @throws InvalidArgumentException If the table name is not a valid identifier
  162.   * @param string $table Category table name, e.g. 'articles_cat_list'
  163.   * @return string Main table name, e.g. 'articles'
  164.   **/
  165. public static function tableCat2main($table)
  166. {
  167. if ($table == '') throw new InvalidArgumentException();
  168. $table = Inflector::plural(str_replace('_cat_list', '', $table));
  169. Pdb::validateIdentifier($table);
  170. return $table;
  171. }
  172.  
  173.  
  174. /**
  175.   * Inserts a record into a category.
  176.   * @param string $table The 'main' table (e.g. 'articles')
  177.   * @param int $record_id The id in the main table.
  178.   * @param int $category_id The id in the category table.
  179.   * @return bool True if adding the record to the category succeeded
  180.   */
  181. public static function insertInto($table, $record_id, $category_id)
  182. {
  183. $table_joiner = self::tableMain2joiner($table);
  184. $record_col = Inflector::singular($table) . '_id';
  185. $category_col = 'cat_id';
  186.  
  187. $update_data = array();
  188. $update_data[$record_col] = $record_id;
  189. $update_data[$category_col] = $category_id;
  190.  
  191. try {
  192. Pdb::insert($table_joiner, $update_data);
  193. } catch (ConstraintQueryException $ex) {
  194. return false;
  195. }
  196.  
  197. return true;
  198. }
  199.  
  200.  
  201. /**
  202.   * Removes a record from a category.
  203.   * Returns true on success and false on failure
  204.   *
  205.   * @param string $table The 'main' table (e.g. 'articles')
  206.   * @param int $record_id The id in the main table.
  207.   * @param int $category_id The id in the category table.
  208.   **/
  209. public static function removefrom($table, $record_id, $category_id)
  210. {
  211. $table_joiner = self::tableMain2joiner($table);
  212. $record_col = Inflector::singular($table) . '_id';
  213. $category_col = 'cat_id';
  214.  
  215. $conditions = array();
  216. $conditions[$record_col] = $record_id;
  217. $conditions[$category_col] = $category_id;
  218.  
  219. try {
  220. Pdb::delete($table_joiner, $conditions);
  221. } catch (ConstraintQueryException $ex) {
  222. return false;
  223. }
  224.  
  225. return true;
  226. }
  227.  
  228.  
  229. /**
  230.   * Does a given category contatin a given record?
  231.   * Returns true if found, false otherwise
  232.   *
  233.   * @param string $table The 'main' table (e.g. 'articles')
  234.   * @param int $record_id The id in the main table.
  235.   * @param int $category_id The id in the category table.
  236.   **/
  237. public static function contains($table, $record_id, $category_id)
  238. {
  239. $record_id = (int) $record_id;
  240. $category_id = (int) $category_id;
  241.  
  242. $table_joiner = self::tableMain2joiner($table);
  243. $record_col = Inflector::singular($table) . '_id';
  244. $category_col = 'cat_id';
  245.  
  246. $q = "SELECT 1 FROM ~{$table_joiner}
  247. WHERE {$record_col} = ? AND {$category_col} = ?";
  248. $res = Pdb::q($q, [$record_id, $category_id], 'arr');
  249.  
  250. if (count($res) == 0) return false;
  251.  
  252. return true;
  253. }
  254.  
  255.  
  256. /**
  257.   * Return an array of IDs of records in a given category.
  258.   * If there are no records, returns an empty array.
  259.   *
  260.   * @param string $table The 'main' table (e.g. 'articles')
  261.   * @param int $category_id The id in the category table.
  262.   **/
  263. public static function recordList($table, $category_id)
  264. {
  265. $category_id = (int) $category_id;
  266.  
  267. $table_joiner = self::tableMain2joiner($table);
  268. $record_col = Inflector::singular($table) . '_id';
  269. $category_col = 'cat_id';
  270.  
  271. $q = "SELECT {$record_col} AS id FROM ~{$table_joiner} WHERE {$category_col} = ?";
  272. return Pdb::q($q, [$category_id], 'col');
  273. }
  274.  
  275.  
  276. /**
  277.   * Return an array of IDs of categories a record is in.
  278.   * If there are no categories, returns an empty array.
  279.   *
  280.   * @param string $table The 'main' table (e.g. 'articles')
  281.   * @param int $record_id The id in the main table.
  282.   **/
  283. public static function categoryList($table, $record_id)
  284. {
  285. $record_id = (int) $record_id;
  286.  
  287. $table_joiner = self::tableMain2joiner($table);
  288. $record_col = Inflector::singular($table) . '_id';
  289.  
  290. $q = "SELECT cat_id AS id FROM ~{$table_joiner} WHERE {$record_col} = ?";
  291. return Pdb::q($q, [$record_id], 'col');
  292. }
  293.  
  294. }
  295.  
  296.