PageRenderTime 69ms CodeModel.GetById 39ms RepoModel.GetById 0ms app.codeStats 0ms

/app/models/ca_places.php

https://bitbucket.org/Sinfin/pawtucket
PHP | 524 lines | 338 code | 56 blank | 130 comment | 16 complexity | ab2f0eb27f525fdc3737bd8c2522093b MD5 | raw file
Possible License(s): LGPL-3.0, GPL-3.0
  1. <?php
  2. /** ---------------------------------------------------------------------
  3. * app/models/ca_places.php : table access class for table ca_places
  4. * ----------------------------------------------------------------------
  5. * CollectiveAccess
  6. * Open-source collections management software
  7. * ----------------------------------------------------------------------
  8. *
  9. * Software by Whirl-i-Gig (http://www.whirl-i-gig.com)
  10. * Copyright 2008-2011 Whirl-i-Gig
  11. *
  12. * For more information visit http://www.CollectiveAccess.org
  13. *
  14. * This program is free software; you may redistribute it and/or modify it under
  15. * the terms of the provided license as published by Whirl-i-Gig
  16. *
  17. * CollectiveAccess is distributed in the hope that it will be useful, but
  18. * WITHOUT ANY WARRANTIES whatsoever, including any implied warranty of
  19. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  20. *
  21. * This source code is free and modifiable under the terms of
  22. * GNU General Public License. (http://www.gnu.org/copyleft/gpl.html). See
  23. * the "license.txt" file for details, or visit the CollectiveAccess web site at
  24. * http://www.CollectiveAccess.org
  25. *
  26. * @package CollectiveAccess
  27. * @subpackage models
  28. * @license http://www.gnu.org/copyleft/gpl.html GNU Public License version 3
  29. *
  30. * ----------------------------------------------------------------------
  31. */
  32. /**
  33. *
  34. */
  35. require_once(__CA_LIB_DIR__."/ca/IBundleProvider.php");
  36. require_once(__CA_LIB_DIR__."/ca/BundlableLabelableBaseModelWithAttributes.php");
  37. require_once(__CA_LIB_DIR__.'/ca/IHierarchy.php');
  38. require_once(__CA_MODELS_DIR__."/ca_lists.php");
  39. BaseModel::$s_ca_models_definitions['ca_places'] = array(
  40. 'NAME_SINGULAR' => _t('place'),
  41. 'NAME_PLURAL' => _t('places'),
  42. 'FIELDS' => array(
  43. 'place_id' => array(
  44. 'FIELD_TYPE' => FT_NUMBER, 'DISPLAY_TYPE' => DT_HIDDEN,
  45. 'IDENTITY' => true, 'DISPLAY_WIDTH' => 10, 'DISPLAY_HEIGHT' => 1,
  46. 'IS_NULL' => false,
  47. 'DEFAULT' => '',
  48. 'LABEL' => 'Place id', 'DESCRIPTION' => 'Identifier for Place'
  49. ),
  50. 'parent_id' => array(
  51. 'FIELD_TYPE' => FT_NUMBER, 'DISPLAY_TYPE' => DT_HIDDEN,
  52. 'DISPLAY_WIDTH' => 10, 'DISPLAY_HEIGHT' => 1,
  53. 'IS_NULL' => true,
  54. 'DEFAULT' => '',
  55. 'LABEL' => 'Parent id', 'DESCRIPTION' => 'Parent id'
  56. ),
  57. 'locale_id' => array(
  58. 'FIELD_TYPE' => FT_NUMBER, 'DISPLAY_TYPE' => DT_SELECT,
  59. 'DISPLAY_WIDTH' => 40, 'DISPLAY_HEIGHT' => 1,
  60. 'IS_NULL' => true,
  61. 'DISPLAY_FIELD' => array('ca_locales.name'),
  62. 'DEFAULT' => '',
  63. 'LABEL' => _t('Locale'), 'DESCRIPTION' => _t('The primary locale associated with the place.')
  64. ),
  65. 'type_id' => array(
  66. 'FIELD_TYPE' => FT_NUMBER, 'DISPLAY_TYPE' => DT_SELECT,
  67. 'DISPLAY_WIDTH' => 10, 'DISPLAY_HEIGHT' => 1,
  68. 'IS_NULL' => true,
  69. 'DEFAULT' => '',
  70. 'LIST_CODE' => 'place_types',
  71. 'LABEL' => _t('Type'), 'DESCRIPTION' => _t('The type of the place. In CollectiveAccess every place has a single "instrinsic" type that determines the set of descriptive and administrative metadata that can be applied to it.')
  72. ),
  73. 'source_id' => array(
  74. 'FIELD_TYPE' => FT_NUMBER, 'DISPLAY_TYPE' => DT_SELECT,
  75. 'DISPLAY_WIDTH' => 10, 'DISPLAY_HEIGHT' => 1,
  76. 'IS_NULL' => true,
  77. 'DEFAULT' => '',
  78. 'LIST_CODE' => 'place_sources',
  79. 'LABEL' => _t('Source'), 'DESCRIPTION' => _t('Administrative source of the place. This value is often used to indicate the administrative sub-division or legacy database from which the place information originates, but can also be re-tasked for use as a simple classification tool if needed.')
  80. ),
  81. 'hierarchy_id' => array(
  82. 'FIELD_TYPE' => FT_NUMBER, 'DISPLAY_TYPE' => DT_OMIT,
  83. 'DISPLAY_WIDTH' => 10, 'DISPLAY_HEIGHT' => 1,
  84. 'IS_NULL' => false,
  85. 'DEFAULT' => '',
  86. 'LIST_CODE' => 'place_hierarchies',
  87. 'LABEL' => 'Place hierarchy', 'DESCRIPTION' => 'Hierarchy this place belongs to.'
  88. ),
  89. 'idno' => array(
  90. 'FIELD_TYPE' => FT_TEXT, 'DISPLAY_TYPE' => DT_FIELD,
  91. 'DISPLAY_WIDTH' => 40, 'DISPLAY_HEIGHT' => 1,
  92. 'IS_NULL' => false,
  93. 'DEFAULT' => '',
  94. 'LABEL' => _t('Place identifier'), 'DESCRIPTION' => _t('Unique identifier for place'),
  95. 'BOUNDS_LENGTH' => array(0,255)
  96. ),
  97. 'idno_sort' => array(
  98. 'FIELD_TYPE' => FT_TEXT, 'DISPLAY_TYPE' => DT_OMIT,
  99. 'DISPLAY_WIDTH' => 255, 'DISPLAY_HEIGHT' => 1,
  100. 'IS_NULL' => false,
  101. 'DEFAULT' => '',
  102. 'LABEL' => 'Idno sort', 'DESCRIPTION' => 'Sortable version of value in idno',
  103. 'BOUNDS_LENGTH' => array(0,255)
  104. ),
  105. 'source_info' => array(
  106. 'FIELD_TYPE' => FT_VARS, 'DISPLAY_TYPE' => DT_OMIT,
  107. 'DISPLAY_WIDTH' => 88, 'DISPLAY_HEIGHT' => 15,
  108. 'IS_NULL' => false,
  109. 'DEFAULT' => '',
  110. 'LABEL' => 'Source information', 'DESCRIPTION' => 'Serialized array used to store source information for place information retrieved via web services [NOT IMPLEMENTED YET].'
  111. ),
  112. 'lifespan' => array(
  113. 'FIELD_TYPE' => FT_HISTORIC_DATERANGE, 'DISPLAY_TYPE' => DT_FIELD,
  114. 'DISPLAY_WIDTH' => 40, 'DISPLAY_HEIGHT' => 1,
  115. 'IS_NULL' => true,
  116. 'DEFAULT' => '', 'START' => 'lifespan_sdate', 'END' => 'lifespan_edate',
  117. 'LABEL' => _t('Lifespan'), 'DESCRIPTION' => _t('Lifespan of place (range of dates)')
  118. ),
  119. 'access' => array(
  120. 'FIELD_TYPE' => FT_NUMBER, 'DISPLAY_TYPE' => DT_SELECT,
  121. 'DISPLAY_WIDTH' => 40, 'DISPLAY_HEIGHT' => 1,
  122. 'IS_NULL' => false,
  123. 'DEFAULT' => 0,
  124. 'BOUNDS_CHOICE_LIST' => array(
  125. _t('Not accessible to public') => 0,
  126. _t('Accessible to public') => 1
  127. ),
  128. 'LIST' => 'access_statuses',
  129. 'LABEL' => _t('Access'), 'DESCRIPTION' => _t('Indicates if place information is accessible to the public or not. ')
  130. ),
  131. 'status' => array(
  132. 'FIELD_TYPE' => FT_NUMBER, 'DISPLAY_TYPE' => DT_SELECT,
  133. 'DISPLAY_WIDTH' => 40, 'DISPLAY_HEIGHT' => 1,
  134. 'IS_NULL' => false,
  135. 'DEFAULT' => 0,
  136. 'BOUNDS_CHOICE_LIST' => array(
  137. _t('Newly created') => 0,
  138. _t('Editing in progress') => 1,
  139. _t('Editing complete - pending review') => 2,
  140. _t('Review in progress') => 3,
  141. _t('Completed') => 4
  142. ),
  143. 'LIST' => 'workflow_statuses',
  144. 'LABEL' => _t('Status'), 'DESCRIPTION' => _t('Indicates the current state of the place record.')
  145. ),
  146. 'deleted' => array(
  147. 'FIELD_TYPE' => FT_BIT, 'DISPLAY_TYPE' => DT_OMIT,
  148. 'DISPLAY_WIDTH' => 10, 'DISPLAY_HEIGHT' => 1,
  149. 'IS_NULL' => false,
  150. 'DEFAULT' => 0,
  151. 'LABEL' => _t('Is deleted?'), 'DESCRIPTION' => _t('Indicates if the place is deleted or not.'),
  152. 'BOUNDS_VALUE' => array(0,1)
  153. ),
  154. 'hier_left' => array(
  155. 'FIELD_TYPE' => FT_NUMBER, 'DISPLAY_TYPE' => DT_OMIT,
  156. 'DISPLAY_WIDTH' => 10, 'DISPLAY_HEIGHT' => 1,
  157. 'IS_NULL' => false,
  158. 'DEFAULT' => '',
  159. 'LABEL' => 'Hierarchical index - left bound', 'DESCRIPTION' => 'Left-side boundary for nested set-style hierarchical indexing; used to accelerate search and retrieval of hierarchical record sets.'
  160. ),
  161. 'hier_right' => array(
  162. 'FIELD_TYPE' => FT_NUMBER, 'DISPLAY_TYPE' => DT_OMIT,
  163. 'DISPLAY_WIDTH' => 10, 'DISPLAY_HEIGHT' => 1,
  164. 'IS_NULL' => false,
  165. 'DEFAULT' => '',
  166. 'LABEL' => 'Hierarchical index - right bound', 'DESCRIPTION' => 'Right-side boundary for nested set-style hierarchical indexing; used to accelerate search and retrieval of hierarchical record sets.'
  167. ),
  168. 'rank' => array(
  169. 'FIELD_TYPE' => FT_NUMBER, 'DISPLAY_TYPE' => DT_FIELD,
  170. 'DISPLAY_WIDTH' => 10, 'DISPLAY_HEIGHT' => 1,
  171. 'IS_NULL' => false,
  172. 'DEFAULT' => '',
  173. 'LABEL' => _t('Sort order'), 'DESCRIPTION' => _t('Sort order'),
  174. )
  175. )
  176. );
  177. class ca_places extends BundlableLabelableBaseModelWithAttributes implements IBundleProvider, IHierarchy {
  178. # ---------------------------------
  179. # --- Object attribute properties
  180. # ---------------------------------
  181. # Describe structure of content object's properties - eg. database fields and their
  182. # associated types, what modes are supported, et al.
  183. #
  184. # ------------------------------------------------------
  185. # --- Basic object parameters
  186. # ------------------------------------------------------
  187. # what table does this class represent?
  188. protected $TABLE = 'ca_places';
  189. # what is the primary key of the table?
  190. protected $PRIMARY_KEY = 'place_id';
  191. # ------------------------------------------------------
  192. # --- Properties used by standard editing scripts
  193. #
  194. # These class properties allow generic scripts to properly display
  195. # records from the table represented by this class
  196. #
  197. # ------------------------------------------------------
  198. # Array of fields to display in a listing of records from this table
  199. protected $LIST_FIELDS = array('idno');
  200. # When the list of "list fields" above contains more than one field,
  201. # the LIST_DELIMITER text is displayed between fields as a delimiter.
  202. # This is typically a comma or space, but can be any string you like
  203. protected $LIST_DELIMITER = ' ';
  204. # What you'd call a single record from this table (eg. a "person")
  205. protected $NAME_SINGULAR;
  206. # What you'd call more than one record from this table (eg. "people")
  207. protected $NAME_PLURAL;
  208. # List of fields to sort listing of records by; you can use
  209. # SQL 'ASC' and 'DESC' here if you like.
  210. protected $ORDER_BY = array('idno');
  211. # Maximum number of record to display per page in a listing
  212. protected $MAX_RECORDS_PER_PAGE = 20;
  213. # How do you want to page through records in a listing: by number pages ordered
  214. # according to your setting above? Or alphabetically by the letters of the first
  215. # LIST_FIELD?
  216. protected $PAGE_SCHEME = 'alpha'; # alpha [alphabetical] or num [numbered pages; default]
  217. # If you want to order records arbitrarily, add a numeric field to the table and place
  218. # its name here. The generic list scripts can then use it to order table records.
  219. protected $RANK = 'rank';
  220. # ------------------------------------------------------
  221. # Hierarchical table properties
  222. # ------------------------------------------------------
  223. protected $HIERARCHY_TYPE = __CA_HIER_TYPE_MULTI_MONO__;
  224. protected $HIERARCHY_LEFT_INDEX_FLD = 'hier_left';
  225. protected $HIERARCHY_RIGHT_INDEX_FLD = 'hier_right';
  226. protected $HIERARCHY_PARENT_ID_FLD = 'parent_id';
  227. protected $HIERARCHY_DEFINITION_TABLE = 'ca_list_items';
  228. protected $HIERARCHY_ID_FLD = 'hierarchy_id';
  229. protected $HIERARCHY_POLY_TABLE = null;
  230. # ------------------------------------------------------
  231. # Change logging
  232. # ------------------------------------------------------
  233. protected $UNIT_ID_FIELD = null;
  234. protected $LOG_CHANGES_TO_SELF = true;
  235. protected $LOG_CHANGES_USING_AS_SUBJECT = array(
  236. "FOREIGN_KEYS" => array(
  237. ),
  238. "RELATED_TABLES" => array(
  239. )
  240. );
  241. # ------------------------------------------------------
  242. # Labeling
  243. # ------------------------------------------------------
  244. protected $LABEL_TABLE_NAME = 'ca_place_labels';
  245. # ------------------------------------------------------
  246. # Attributes
  247. # ------------------------------------------------------
  248. protected $ATTRIBUTE_TYPE_ID_FLD = 'type_id'; // name of type field for this table - attributes system uses this to determine via ca_metadata_type_restrictions which attributes are applicable to rows of the given type
  249. protected $ATTRIBUTE_TYPE_LIST_CODE = 'place_types'; // list code (ca_lists.list_code) of list defining types for this table
  250. # ------------------------------------------------------
  251. # Self-relations
  252. # ------------------------------------------------------
  253. protected $SELF_RELATION_TABLE_NAME = 'ca_places_x_places';
  254. # ------------------------------------------------------
  255. # ID numbering
  256. # ------------------------------------------------------
  257. protected $ID_NUMBERING_ID_FIELD = 'idno'; // name of field containing user-defined identifier
  258. protected $ID_NUMBERING_SORT_FIELD = 'idno_sort'; // name of field containing version of identifier for sorting (is normalized with padding to sort numbers properly)
  259. protected $ID_NUMBERING_CONTEXT_FIELD = 'hierarchy_id'; // name of field to use value of for "context" when checking for duplicate identifier values; if not set identifer is assumed to be global in scope; if set identifer is checked for uniqueness (if required) within the value of this field
  260. # ------------------------------------------------------
  261. # Search
  262. # ------------------------------------------------------
  263. protected $SEARCH_CLASSNAME = 'PlaceSearch';
  264. protected $SEARCH_RESULT_CLASSNAME = 'PlaceSearchResult';
  265. # ------------------------------------------------------
  266. # $FIELDS contains information about each field in the table. The order in which the fields
  267. # are listed here is the order in which they will be returned using getFields()
  268. protected $FIELDS;
  269. # ------------------------------------------------------
  270. # --- Constructor
  271. #
  272. # This is a function called when a new instance of this object is created. This
  273. # standard constructor supports three calling modes:
  274. #
  275. # 1. If called without parameters, simply creates a new, empty objects object
  276. # 2. If called with a single, valid primary key value, creates a new objects object and loads
  277. # the record identified by the primary key value
  278. #
  279. # ------------------------------------------------------
  280. public function __construct($pn_id=null) {
  281. parent::__construct($pn_id); # call superclass constructor
  282. }
  283. # ------------------------------------------------------
  284. protected function initLabelDefinitions() {
  285. parent::initLabelDefinitions();
  286. $this->BUNDLES['ca_entities'] = array('type' => 'related_table', 'repeating' => true, 'label' => _t('Related entities'));
  287. $this->BUNDLES['ca_objects'] = array('type' => 'related_table', 'repeating' => true, 'label' => _t('Related objects'));
  288. $this->BUNDLES['ca_places'] = array('type' => 'related_table', 'repeating' => true, 'label' => _t('Related places'));
  289. $this->BUNDLES['ca_collections'] = array('type' => 'related_table', 'repeating' => true, 'label' => _t('Related collections'));
  290. $this->BUNDLES['ca_occurrences'] = array('type' => 'related_table', 'repeating' => true, 'label' => _t('Related occurrences'));
  291. $this->BUNDLES['ca_list_items'] = array('type' => 'related_table', 'repeating' => true, 'label' => _t('Related vocabulary terms'));
  292. $this->BUNDLES['hierarchy_navigation'] = array('type' => 'special', 'repeating' => false, 'label' => _t('Hierarchy navigation'));
  293. $this->BUNDLES['hierarchy_location'] = array('type' => 'special', 'repeating' => false, 'label' => _t('Location in hierarchy'));
  294. }
  295. # ------------------------------------------------------
  296. /**
  297. * Returns a flat list of all entities in the specified list referenced by items in the specified table
  298. * (and optionally a search on that table)
  299. */
  300. public function getReferenced($pm_table_num_or_name, $pn_type_id=null, $pa_reference_limit_ids=null, $pn_access=null) {
  301. if (is_numeric($pm_table_num_or_name)) {
  302. $vs_table_name = $this->getAppDataModel()->getTableName($pm_table_num_or_name);
  303. } else {
  304. $vs_table_name = $pm_table_num_or_name;
  305. }
  306. if (!($t_ref_table = $this->getAppDatamodel()->getInstanceByTableName($vs_table_name, true))) {
  307. return null;
  308. }
  309. if (!$vs_table_name) { return null; }
  310. $o_db = $this->getDb();
  311. $va_path = $this->getAppDatamodel()->getPath($this->tableName(), $vs_table_name);
  312. array_shift($va_path); // remove table name from path
  313. $vs_last_table = $this->tableName();
  314. $va_joins = array();
  315. foreach($va_path as $vs_rel_table_name => $vn_rel_table_num) {
  316. $va_rels = $this->getAppDatamodel()->getRelationships($vs_last_table, $vs_rel_table_name);
  317. $va_rel = $va_rels[$vs_last_table][$vs_rel_table_name][0];
  318. $va_joins[] = "INNER JOIN {$vs_rel_table_name} ON {$vs_last_table}.".$va_rel[0]." = {$vs_rel_table_name}.".$va_rel[1];
  319. $vs_last_table = $vs_rel_table_name;
  320. }
  321. $va_sql_wheres = array();
  322. if (is_array($pa_reference_limit_ids) && sizeof($pa_reference_limit_ids)) {
  323. $va_sql_wheres[] = "({$vs_table_name}.".$t_ref_table->primaryKey()." IN (".join(',', $pa_reference_limit_ids)."))";
  324. }
  325. if (!is_null($pn_access)) {
  326. $va_sql_wheres[] = "({$vs_table_name}.access = ".intval($pn_access).")";
  327. }
  328. // get place counts
  329. $vs_sql = "
  330. SELECT ca_places.place_id, count(*) cnt
  331. FROM ca_places
  332. ".join("\n", $va_joins)."
  333. ".(sizeof($va_sql_wheres) ? " WHERE ".join(' AND ', $va_sql_wheres) : "")."
  334. GROUP BY
  335. ca_places.place_id, {$vs_table_name}.".$t_ref_table->primaryKey()."
  336. ";
  337. $qr_items = $o_db->query($vs_sql);
  338. $va_item_counts = array();
  339. while($qr_items->nextRow()) {
  340. $va_item_counts[$qr_items->get('place_id')]++;
  341. }
  342. $vs_sql = "
  343. SELECT ca_places.place_id, ca_places.idno, ca_place_labels.*, count(*) c
  344. FROM ca_places
  345. INNER JOIN ca_place_labels ON ca_place_labels.place_id = ca_places.place_id
  346. ".join("\n", $va_joins)."
  347. WHERE
  348. (ca_place_labels.is_preferred = 1)
  349. ".(sizeof($va_sql_wheres) ? " AND ".join(' AND ', $va_sql_wheres) : "")."
  350. GROUP BY
  351. ca_place_labels.label_id
  352. ORDER BY
  353. ca_place_labels.name
  354. ";
  355. $qr_items = $o_db->query($vs_sql);
  356. $va_items = array();
  357. while($qr_items->nextRow()) {
  358. $vn_place_id = $qr_items->get('place_id');
  359. $va_items[$vn_place_id][$qr_items->get('locale_id')] = array_merge($qr_items->getRow(), array('cnt' => $va_item_counts[$vn_place_id]));
  360. }
  361. return caExtractValuesByUserLocale($va_items);
  362. }
  363. # ------------------------------------------------------
  364. /**
  365. * Return array containing information about all place hierarchies, including their root_id's
  366. */
  367. public function getHierarchyList($pb_dummy=false) {
  368. $t_list = new ca_lists();
  369. $va_place_hierarchies = caExtractValuesByUserLocale($t_list->getItemsForList('place_hierarchies'));
  370. $o_db = $this->getDb();
  371. $va_hierarchy_ids = array();
  372. foreach($va_place_hierarchies as $vn_i => $va_item) {
  373. $va_hierarchy_ids[] = intval($va_item['item_id']);
  374. }
  375. if (!sizeof($va_hierarchy_ids)) { return array(); }
  376. // get root for each hierarchy
  377. $qr_res = $o_db->query("
  378. SELECT p.place_id, p.hierarchy_id, count(*) children
  379. FROM ca_places p
  380. INNER JOIN ca_places AS p2 ON p.place_id = p2.place_id
  381. WHERE
  382. p.parent_id IS NULL and p.hierarchy_id IN (".join(',', $va_hierarchy_ids).")
  383. GROUP BY
  384. p.place_id
  385. ");
  386. while ($qr_res->nextRow()) {
  387. $vn_hierarchy_id = $qr_res->get('hierarchy_id');
  388. $va_place_hierarchies[$vn_hierarchy_id]['place_id'] = $qr_res->get('place_id');
  389. $va_place_hierarchies[$vn_hierarchy_id]['name'] = $va_place_hierarchies[$vn_hierarchy_id]['name_plural'];
  390. $va_place_hierarchies[$vn_hierarchy_id]['children'] = $qr_res->get('children');
  391. }
  392. return $va_place_hierarchies;
  393. }
  394. # ------------------------------------------------------
  395. /**
  396. * Returns name of hierarchy for currently loaded place or, if specified, place with place_id = to optional $pn_id parameter
  397. */
  398. public function getHierarchyName($pn_id=null) {
  399. $t_list = new ca_lists();
  400. if ($pn_id) {
  401. $t_place = new ca_places($pn_id);
  402. $vn_hierarchy_id = $t_place->get('hierarchy_id');
  403. } else {
  404. $vn_hierarchy_id = $this->get('hierarchy_id');
  405. }
  406. $t_list->load($vn_hierarchy_id);
  407. return $t_list->getLabelForDisplay(false);
  408. }
  409. # ------------------------------------------------------
  410. /**
  411. * Returns the place_id in ca_places table for root of specified hierarchy. Place hierarchies are enumerated in the "place_hierarchies" list,
  412. * so hierarchy specifications are really just plain old list items (ca_list_items records). You can specify a hierarchy using an hierarchy id
  413. * (really just a ca_list_items item_id value for the item representing the hierarchy), or by passing the idno of the hierarchy (eg. ca_list_items.idno).
  414. *
  415. * @param mixed $pm_hierarchy_code_or_id The numeric id or alphanumeric code for the hierarchy. Since hierarchies are represented with list items these are the item_id or idno values of the hierarchy's list item.
  416. * @return int Place ID of the place hierarchy root
  417. */
  418. public function getRootIDForHierarchy($pm_hierarchy_code_or_id) {
  419. $o_db = $this->getDb();
  420. if (!is_numeric($pm_hierarchy_code_or_id)) {
  421. $t_list = new ca_lists();
  422. $pn_hierarchy_id = (int)$t_list->getItemIDFromList('place_hierarchies', $pm_hierarchy_code_or_id);
  423. } else {
  424. $pn_hierarchy_id = (int)$pm_hierarchy_code_or_id;
  425. }
  426. $qr_res = $o_db->query("
  427. SELECT place_id
  428. FROM ca_places
  429. WHERE
  430. (parent_id IS NULL) AND (hierarchy_id = ?)
  431. ", (int)$pn_hierarchy_id);
  432. if ($qr_res->nextRow()) {
  433. return $qr_res->get('place_id');
  434. }
  435. return null;
  436. }
  437. # ------------------------------------------------------
  438. /**
  439. *
  440. */
  441. public function getPlaceIDsByName($ps_name, $pn_parent_id=null) {
  442. $o_db = $this->getDb();
  443. if ($pn_parent_id) {
  444. $qr_res = $o_db->query("
  445. SELECT DISTINCT cap.place_id
  446. FROM ca_places cap
  447. INNER JOIN ca_place_labels AS capl ON capl.place_id = cap.place_id
  448. WHERE
  449. capl.name = ? AND cap.parent_id = ?
  450. ", (string)$ps_name, (int)$pn_parent_id);
  451. } else {
  452. $qr_res = $o_db->query("
  453. SELECT DISTINCT cap.place_id
  454. FROM ca_places cap
  455. INNER JOIN ca_place_labels AS capl ON capl.place_id = cap.place_id
  456. WHERE
  457. capl.name = ?
  458. ", (string)$ps_name);
  459. }
  460. $va_place_ids = array();
  461. while($qr_res->nextRow()) {
  462. $va_place_ids[] = $qr_res->get('place_id');
  463. }
  464. return $va_place_ids;
  465. }
  466. # ------------------------------------------------------
  467. }
  468. ?>