PageRenderTime 27ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 0ms

/lib/People/DatabasePeopleRetriever.php

http://github.com/modolabs/Kurogo-Mobile-Web
PHP | 280 lines | 203 code | 54 blank | 23 comment | 17 complexity | 37dde7f05dc62fef90f57518ae378319 MD5 | raw file
Possible License(s): LGPL-3.0, LGPL-2.1
  1. <?php
  2. /*
  3. * Copyright © 2010 - 2013 Modo Labs Inc. All rights reserved.
  4. *
  5. * The license governing the contents of this file is located in the LICENSE
  6. * file located at the root directory of this distribution. If the LICENSE file
  7. * is missing, please contact sales@modolabs.com.
  8. *
  9. */
  10. /**
  11. * @package People
  12. */
  13. /**
  14. * @package People
  15. */
  16. class DatabasePeopleRetriever extends DatabaseDataRetriever implements PeopleRetriever {
  17. const MIN_NAME_SEARCH = 3;
  18. protected $DEFAULT_PARSER_CLASS = 'DatabasePeopleParser';
  19. protected $table;
  20. protected $fieldMap=array();
  21. protected $personClass = 'DatabasePerson';
  22. protected $sortFields=array('lastname','firstname');
  23. protected $attributes = array();
  24. protected $searchFields = array();
  25. public function debugInfo() {
  26. return sprintf("Using Database");
  27. }
  28. public function getCacheKey() {
  29. return false;
  30. }
  31. protected function getSearchFields() {
  32. if ($this->searchFields) {
  33. $defaultFields = array(
  34. $this->getField('firstname'),
  35. $this->getField('lastname'),
  36. $this->getField('email')
  37. );
  38. if ($searchFields = array_diff($this->searchFields, $defaultFields)) {
  39. return array_unique($searchFields);
  40. }
  41. }
  42. return null;
  43. }
  44. protected function buildSearchQuery($searchString) {
  45. $sql = "";
  46. $parameters = array();
  47. if (empty($searchString)) {
  48. $this->errorMsg = "Query was blank";
  49. return;
  50. } elseif (Validator::isValidEmail($searchString)) {
  51. $sql = sprintf("SELECT %s FROM %s WHERE %s LIKE ?", '*', $this->table, $this->getField('email'));
  52. $parameters = array('%'.$searchString.'%');
  53. } elseif ($this->getField('phone') && Validator::isValidPhone($searchString, $phone_bits)) {
  54. array_shift($phone_bits);
  55. $searchString = implode("", $phone_bits); // remove any separators. This might be an issue for people with formatted numbers in their directory
  56. $sql = sprintf("SELECT %s FROM %s WHERE %s LIKE ?", '*', $this->table, $this->getField('phone'));
  57. $parameters = array($searchString.'%');
  58. } elseif ($this->getField('phone') && preg_match('/^[0-9]+/', $searchString)) { //partial phone number
  59. $sql = sprintf("SELECT %s FROM %s WHERE %s LIKE ?", '*', $this->table, $this->getField('phone'));
  60. $parameters = array($searchString.'%');
  61. } elseif (strlen(trim($searchString)) < self::MIN_NAME_SEARCH) {
  62. $sql = sprintf("SELECT %s FROM %s WHERE %s = ? OR %s = ?", '*', $this->table, $this->getField('firstname'), $this->getField('lastname'));
  63. $parameters = array($searchString, $searchString);
  64. } elseif (preg_match('/[A-Za-z]+/', $searchString)) { // assume search by name
  65. $names = preg_split("/\s+/", $searchString);
  66. $nameCount = count($names);
  67. $where = array();
  68. switch ($nameCount)
  69. {
  70. case 1:
  71. //try first name, last name and email
  72. $where = sprintf("(%s LIKE ? OR %s LIKE ? OR %s LIKE ?)", $this->getField('firstname'), $this->getField('lastname'), $this->getField('email'));
  73. $parameters = array($searchString.'%', $searchString.'%', '%'.$searchString.'%');
  74. break;
  75. case 2:
  76. $where = sprintf("((%s LIKE ? AND %s LIKE ?) OR (%s LIKE ? AND %s LIKE ?))",
  77. $this->getField('firstname'), $this->getField('lastname'),
  78. $this->getField('lastname'), $this->getField('firstname')
  79. );
  80. $parameters = array($names[0].'%', $names[1].'%', $names[0].'%', $names[1].'%');
  81. break;
  82. default:
  83. // Either the first word is the first name, or it's a title and the
  84. // second word is the first name.
  85. $possibleFirstNames = array($names[0], $names[1]);
  86. // Either the last word is the last name, or the last two words taken
  87. // together are the last name.
  88. $possibleLastNames = array($names[$nameCount - 1],
  89. $names[$nameCount - 2] . " " . $names[$nameCount - 1]);
  90. $parameters = array();
  91. foreach ($possibleFirstNames as $i => $firstName) {
  92. foreach ($possibleLastNames as $j => $lastName) {
  93. $where[] = sprintf("(%s LIKE ? AND %s LIKE ?)", $this->getField('firstname'), $this->getField('lastname'));
  94. $parameters[] = $firstName;
  95. $parameters[] = $lastName;
  96. }
  97. }
  98. $where = implode(" OR ", $where);
  99. }
  100. //build search for additional fields
  101. if ($searchField = $this->getSearchFields()) {
  102. $fieldWhere = array();
  103. foreach ($searchField as $field) {
  104. $fieldWhere[] = sprintf("%s LIKE ?", $field);
  105. $parameters[] = "%" . $searchString . "%";
  106. }
  107. $where .= ' OR ' . implode(" OR ", $fieldWhere);
  108. }
  109. $sql = sprintf("SELECT %s FROM %s WHERE %s ORDER BY %s", '*', $this->table, $where, implode(",", array_map(array($this,'getField'),$this->sortFields)));
  110. } else {
  111. $this->errorMsg = "Invalid query";
  112. return false;
  113. }
  114. return array($sql, $parameters);
  115. }
  116. public function search($searchString, &$response=null) {
  117. $this->setQuery($this->buildSearchQuery($searchString));
  118. $this->setOption('action', 'search');
  119. $this->setContext('value', $searchString);
  120. return $this->getData($response);
  121. }
  122. protected function getField($_field) {
  123. if (array_key_exists($_field, $this->fieldMap)) {
  124. return $this->fieldMap[$_field];
  125. }
  126. return $_field;
  127. }
  128. protected function buildUserQuery($id) {
  129. $sql = sprintf("SELECT %s FROM %s WHERE %s=?", '*', $this->table, $this->getField('userid'));
  130. $parameters = array($id);
  131. return array($sql, $parameters);
  132. }
  133. /* returns a person object on success
  134. * FALSE on failure
  135. */
  136. public function getUser($id) {
  137. $this->setQuery($this->buildUserQuery($id));
  138. $this->setOption('action','user');
  139. $this->setContext('value', $id);
  140. return $this->getData($response);
  141. }
  142. public function setAttributes($attributes) {
  143. $this->attributes = $attributes;
  144. }
  145. protected function init($args) {
  146. parent::init($args);
  147. if (isset($args['SORTFIELDS']) && is_array($args['SORTFIELDS'])) {
  148. $this->sortFields = $args['SORTFIELDS'];
  149. }
  150. $this->table = isset($args['DB_USER_TABLE']) ? $args['DB_USER_TABLE'] : 'users';
  151. $this->fieldMap = array(
  152. 'userid'=>isset($args['DB_USERID_FIELD']) ? $args['DB_USERID_FIELD'] : 'userID',
  153. 'email'=>isset($args['DB_EMAIL_FIELD']) ? $args['DB_EMAIL_FIELD'] : 'email',
  154. 'firstname'=>isset($args['DB_FIRSTNAME_FIELD']) ? $args['DB_FIRSTNAME_FIELD'] : 'firstname',
  155. 'lastname'=>isset($args['DB_LASTNAME_FIELD']) ? $args['DB_LASTNAME_FIELD'] : 'lastname',
  156. 'phone'=>isset($args['DB_PHONE_FIELD']) ? $args['DB_PHONE_FIELD'] : ''
  157. );
  158. if (isset($args['SEARCH_FIELDS'])) {
  159. $this->searchFields = $args['SEARCH_FIELDS'];
  160. }
  161. $this->setContext('fieldMap',$this->fieldMap);
  162. }
  163. }
  164. class DatabasePeopleParser extends PeopleDataParser
  165. {
  166. protected $personClass = 'DatabasePerson';
  167. public function parseData($data) {
  168. throw new KurogoException("Parse data not supported");
  169. }
  170. public function parseResponse(DataResponse $response) {
  171. $this->setResponse($response);
  172. $result = $response->getResponse();
  173. if (!$result instanceOf PDOStatement) {
  174. return false;
  175. }
  176. $fieldMap = $response->getContext('fieldMap');
  177. switch ($this->getOption('action')) {
  178. case 'search':
  179. $results = array();
  180. while ($row = $result->fetch()) {
  181. $person = new $this->personClass();
  182. $person->setFieldMap($fieldMap);
  183. $person->setAttributes($row);
  184. $results[] = $person;
  185. }
  186. $this->setTotalItems(count($results));
  187. return $results;
  188. break;
  189. case 'user':
  190. $person = false;
  191. if ($row = $result->fetch()) {
  192. $person = new $this->personClass();
  193. $person->setFieldMap($fieldMap);
  194. $person->setAttributes($row);
  195. }
  196. $result->closeCursor();
  197. $this->setTotalItems($person ? 1 : 0);
  198. return $person;
  199. }
  200. }
  201. }
  202. class DatabasePerson extends Person
  203. {
  204. protected $fieldMap = array();
  205. public function setFieldMap(array $fieldMap) {
  206. $this->fieldMap = $fieldMap;
  207. }
  208. public function getName() {
  209. return sprintf("%s %s",
  210. $this->getField($this->fieldMap['firstname']),
  211. $this->getField($this->fieldMap['lastname']));
  212. }
  213. public function getId() {
  214. return $this->getField(strtolower($this->fieldMap['userid']));
  215. }
  216. public function setAttributes($data) {
  217. foreach ($data as $field=>$value) {
  218. if (strlen($value)>0) {
  219. $this->setField(strtolower($field), $value);
  220. }
  221. }
  222. }
  223. public function getAttributes(){
  224. return $this->attributes;
  225. }
  226. }