PageRenderTime 48ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/framework/classes/core/CASHDBA.php

https://gitlab.com/x33n/platform
PHP | 591 lines | 533 code | 12 blank | 46 comment | 86 complexity | 4f4f2b01278c28a695f87d1e065cdc1e MD5 | raw file
  1. <?php
  2. /**
  3. * No frills DBA connection class using PHP's PDO library. CASHDBA provides
  4. * easy functions for data access using a get/set convention and auto-detection
  5. * of conditions. All database tables are abstracted using a lookupTableName()
  6. * function to centralize any future schema changes.
  7. *
  8. * @package platform.org.cashmusic
  9. * @author CASH Music
  10. * @link http://cashmusic.org/
  11. *
  12. * Copyright (c) 2013, CASH Music
  13. * Licensed under the GNU Lesser General Public License version 3.
  14. * See http://www.gnu.org/licenses/lgpl-3.0.html
  15. *
  16. *
  17. * This file is generously sponsored by Jodi Leo
  18. *
  19. **/
  20. class CASHDBA {
  21. public $error = 'Relax. Everything is okay.';
  22. protected $db;
  23. private $hostname,
  24. $username,
  25. $password,
  26. $dbname,
  27. $driver,
  28. $port;
  29. public function __construct($hostname,$username,$password,$database,$driver) {
  30. if (strpos($hostname,':') === false) {
  31. $this->hostname = $hostname;
  32. $this->port = 3306;
  33. } else {
  34. if (substr($hostname,0,2) == ':/') {
  35. $this->hostname = $hostname;
  36. } else {
  37. $host_and_port = explode(':',$hostname);
  38. $this->hostname = $host_and_port[0];
  39. $this->port = $host_and_port[1];
  40. }
  41. }
  42. $this->username = $username;
  43. $this->password = $password;
  44. $this->dbname = $database;
  45. $this->driver = $driver;
  46. }
  47. public function connect() {
  48. try {
  49. if ($this->driver == 'sqlite') {
  50. $this->db = new PDO("sqlite:" . CASH_PLATFORM_ROOT . "/db/{$this->dbname}");
  51. } else {
  52. if (substr($this->hostname,0,2) == ':/') {
  53. $this->db = new PDO("{$this->driver}:unix_socket={$this->hostname};dbname={$this->dbname}", $this->username, $this->password, array(PDO::ATTR_PERSISTENT => false));
  54. } else {
  55. $this->db = new PDO("{$this->driver}:host={$this->hostname};port={$this->port};dbname={$this->dbname}", $this->username, $this->password, array(PDO::ATTR_PERSISTENT => false));
  56. }
  57. }
  58. $this->db->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
  59. } catch(PDOException $e) {
  60. $this->error = $e->getMessage();
  61. error_log('CASHDBA error: ' . $this->error);
  62. die();
  63. }
  64. }
  65. public function getErrorMessage() {
  66. return $this->error;
  67. }
  68. public function lookupTableName($data_name) {
  69. $table_lookup = array(
  70. 'analytics' => 'system_analytics',
  71. 'assets' => 'assets',
  72. 'assets_analytics' => 'assets_analytics',
  73. 'assets_analytics_basic' => 'assets_analytics_basic',
  74. 'commerce_assets' => 'commerce_assets',
  75. 'connections' => 'system_connections',
  76. 'contacts' => 'people_contacts',
  77. 'elements' => 'elements',
  78. 'elements_analytics' => 'elements_analytics',
  79. 'elements_analytics_basic' => 'elements_analytics_basic',
  80. 'elements_campaigns' => 'elements_campaigns',
  81. 'events' => 'calendar_events',
  82. 'items' => 'commerce_items',
  83. 'lock_codes' => 'system_lock_codes',
  84. 'mailings' => 'people_mailings',
  85. 'mailings_analytics' => 'people_mailings_analytics',
  86. 'metadata' => 'system_metadata',
  87. 'offers' => 'commerce_offers',
  88. 'orders' => 'commerce_orders',
  89. 'sessions' => 'system_sessions',
  90. 'settings' => 'system_settings',
  91. 'templates' => 'system_templates',
  92. 'users' => 'people',
  93. 'people_analytics' => 'people_analytics',
  94. 'people_analytics_basic' => 'people_analytics_basic',
  95. 'people_lists' => 'people_lists',
  96. 'people_resetpassword' => 'people_resetpassword',
  97. 'list_members' => 'people_lists_members',
  98. 'transactions' => 'commerce_transactions',
  99. 'venues' => 'calendar_venues'
  100. );
  101. if (array_key_exists($data_name, $table_lookup)) {
  102. return $table_lookup[$data_name];
  103. } else {
  104. return false;
  105. }
  106. }
  107. public function doQuery($query,$values=false) {
  108. if ($values) {
  109. $q = $this->db->prepare($query);
  110. $q->execute($values);
  111. } else {
  112. $q = $this->db->query($query);
  113. }
  114. $q->setFetchMode(PDO::FETCH_ASSOC);
  115. try {
  116. $result = $q->fetchAll();
  117. } catch(PDOException $e) {
  118. $this->error = $e->getMessage();
  119. error_log('CASHDBA error: ' . $this->error);
  120. }
  121. if ($result) {
  122. if (count($result) == 0) {
  123. return false;
  124. } else {
  125. return $result;
  126. }
  127. }
  128. }
  129. public function getRealTableNames() {
  130. if ($this->driver == 'sqlite') {
  131. $query = 'SELECT name FROM sqlite_master WHERE type=\'table\'';
  132. } else {
  133. $query = 'SELECT DISTINCT(table_name) FROM information_schema.columns WHERE table_schema = \'' . $this->dbname . '\'';
  134. }
  135. if (!is_object($this->db)) {
  136. $this->connect();
  137. }
  138. $result = $this->doQuery($query);
  139. if (is_array($result)) {
  140. // if we got a result, get ready to strip it to just an array of table names
  141. $names_only = array();
  142. foreach ($result as $table) {
  143. // this removes text text key and makes the value easier to reference consistently
  144. $stripped_table = array_values($table);
  145. $names_only[] = $stripped_table[0];
  146. }
  147. // sort alphabetically to return consistent results no matter the DB engine
  148. sort($names_only);
  149. return $names_only;
  150. } else {
  151. return false;
  152. }
  153. }
  154. public function migrateDB($todriver='mysql',$tosettings=false) {
  155. /* for mysql we're expecting a $tosettings array that looks like:
  156. hostname => hostname[:port]
  157. username => username
  158. password => password
  159. database => databasename
  160. */
  161. if ($todriver != 'mysql' || !is_array($tosettings)) {
  162. return false;
  163. } else {
  164. $newdb_hostname = false;
  165. $newdb_port = false;
  166. if (strpos($tosettings['hostname'],':') === false) {
  167. $newdb_hostname = $tosettings['hostname'];
  168. $newdb_port = 3306;
  169. } else {
  170. if (substr($tosettings['hostname'],0,2) == ':/') {
  171. $newdb_hostname = $tosettings['hostname'];
  172. } else {
  173. $host_and_port = explode(':',$tosettings['hostname']);
  174. $newdb_hostname = $host_and_port[0];
  175. $newdb_port = $host_and_port[1];
  176. }
  177. }
  178. if ($newdb_hostname) {
  179. try {
  180. if (substr($this->hostname,0,2) == ':/') {
  181. $newdb = new PDO("$todriver:unix_socket=$newdb_hostname;dbname={$tosettings['database']}", $tosettings['username'], $tosettings['password']);
  182. } else {
  183. $newdb = new PDO("$todriver:host=$newdb_hostname;port=$newdb_port;dbname={$tosettings['database']}", $tosettings['username'], $tosettings['password']);
  184. }
  185. $newdb->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
  186. } catch(PDOException $e) {
  187. return false;
  188. }
  189. // run the baseline sql file — will blow away any old bullshit but leave non-standard tables
  190. if ($newdb->query(file_get_contents(CASH_PLATFORM_ROOT.'/settings/sql/cashmusic_db.sql'))) {
  191. // begin a transaction for the newdb
  192. $newdb->beginTransaction();
  193. // get all the current tables
  194. $current_tables = $this->getRealTableNames();
  195. foreach ($current_tables as $tablename) {
  196. // looping through and starting the CRAAAAZZZZEEEEEE
  197. // first get all data in the current table
  198. $tabledata = $this->doQuery('SELECT * FROM ' . $tablename);
  199. // now jam that junk into an insert on the new db
  200. if (is_array($tabledata)) {
  201. // identifier quote
  202. $quote = '"';
  203. if ($todriver == 'mysql') {
  204. $quote = '`';
  205. }
  206. // we found data, so loop through each one with an insert
  207. foreach ($tabledata as $data) {
  208. $query = "INSERT INTO $tablename (";
  209. $separator = '';
  210. $query_columns = '';
  211. $query_values = '';
  212. foreach ($data as $fieldname => $value) {
  213. $query_columns .= $separator.$quote.$fieldname.$quote;
  214. $query_values .= $separator.':'.$fieldname;
  215. $separator = ',';
  216. }
  217. $query .= "$query_columns) VALUES ($query_values)";
  218. try {
  219. $q = $newdb->prepare($query);
  220. $q->execute($data);
  221. } catch(PDOException $e) {
  222. // something went wrong. roll back and quit
  223. $newdb->rollBack();
  224. return false;
  225. }
  226. }
  227. }
  228. }
  229. // fuckin a right.
  230. $result = $newdb->commit();
  231. if ($result) {
  232. CASHSystem::setSystemSetting('driver',$todriver);
  233. CASHSystem::setSystemSetting('hostname',$tosettings['hostname']);
  234. CASHSystem::setSystemSetting('username',$tosettings['username']);
  235. CASHSystem::setSystemSetting('password',$tosettings['password']);
  236. CASHSystem::setSystemSetting('database',$tosettings['database']);
  237. return $result;
  238. } else {
  239. return $result;
  240. }
  241. }
  242. } else {
  243. return false;
  244. }
  245. }
  246. }
  247. public function parseConditions(&$conditions,$prepared=true) {
  248. $return_str = " WHERE ";
  249. $separator = '';
  250. // identifier quote
  251. $q = '"';
  252. if ($this->driver == 'mysql') {
  253. $q = '`';
  254. }
  255. foreach ($conditions as $value => $details) {
  256. if ($prepared) {
  257. if ($details['condition'] != 'IN') {
  258. $return_str .= $separator . $q . $value . $q . ' ' . $details['condition'] . ' ' . ':where' . $value;
  259. } else {
  260. $return_str .= $separator . $q . $value . $q . ' ' . $details['condition'] . ' (';
  261. $valuecount = 0;
  262. foreach ($details['value'] as $current_value) {
  263. if ($valuecount > 0) {
  264. $return_str .= ",";
  265. }
  266. $conditions[$value . '_' . $valuecount] = array(
  267. 'value' => $current_value
  268. );
  269. $return_str .= ':where' . $value . '_' . $valuecount;
  270. $valuecount++;
  271. }
  272. $return_str .= ')';
  273. }
  274. } else {
  275. if (is_string($details['value'])) {
  276. $query_value = "'" . str_replace("'","\'",$details['value']) . "'";
  277. } else {
  278. $query_value = $details['value'];
  279. }
  280. $return_str .= $separator . $q . $value . $q . ' ' . $details['condition'] . ' ' . $query_value;
  281. }
  282. // support multiple types of separators — only needed for more complex operations
  283. // and this is pretty much either or (combining AND and OR conditions would be trickier)
  284. if (isset($details['separator'])) {
  285. $separator = ' ' . $details['separator'] . ' ';
  286. } else {
  287. $separator = ' AND ';
  288. }
  289. if ($details['condition'] == 'IN') {
  290. unset($conditions[$value]);
  291. }
  292. }
  293. return $return_str;
  294. }
  295. public function getData($data_name,$data,$conditions=false,$limit=false,$orderby=false) {
  296. if (!is_object($this->db)) {
  297. $this->connect();
  298. }
  299. $query = false;
  300. $table_name = $this->lookupTableName($data_name);
  301. if ($table_name === false) {
  302. return $this->getSpecialData($data_name,$conditions,$limit,$orderby);
  303. }
  304. if ($data) {
  305. // identifier quote
  306. $q = '"';
  307. if ($this->driver == 'mysql') {
  308. $q = '`';
  309. }
  310. if (strpos($data,',') !== false) {
  311. $data = $q . str_replace(',', "$q,$q", $data) . $q;
  312. }
  313. $query = "SELECT $data FROM $q$table_name$q";
  314. if ($conditions) {
  315. $query .= $this->parseConditions($conditions);
  316. }
  317. if ($orderby) $query .= " ORDER BY $orderby";
  318. if ($limit) $query .= " LIMIT $limit";
  319. }
  320. if ($query) {
  321. if ($conditions) {
  322. $values_array = array();
  323. foreach ($conditions as $value => $details) {
  324. // any arrays would be vestigal from passed-in "IN" conditions
  325. // — we add to the conditions array in that case so the original
  326. // condition is unneeded and causes an array->string conversion
  327. // warning. so forget it. later dude.
  328. if (!is_array($details['value'])) {
  329. $values_array[':where'.$value] = $details['value'];
  330. }
  331. }
  332. return $this->doQuery($query,$values_array);
  333. } else {
  334. return $this->doQuery($query);
  335. }
  336. } else {
  337. return false;
  338. }
  339. }
  340. public function setData($data_name,$data,$conditions=false) {
  341. if (!is_object($this->db)) {
  342. $this->connect();
  343. }
  344. $query = false;
  345. $table_name = $this->lookupTableName($data_name);
  346. if (is_array($data) && $table_name) {
  347. // identifier quote
  348. $q = '"';
  349. if ($this->driver == 'mysql') {
  350. $q = '`';
  351. }
  352. if ($conditions) {
  353. // if $condition is set then we're doing an UPDATE
  354. $data['modification_date'] = time();
  355. $query = "UPDATE $q$table_name$q SET ";
  356. $separator = '';
  357. foreach ($data as $fieldname => $value) {
  358. $query .= $separator."$q$fieldname$q=:$fieldname";
  359. $separator = ',';
  360. }
  361. $query .= $this->parseConditions($conditions);
  362. $values_array = array();
  363. foreach ($conditions as $value => $details) {
  364. $values_array[':where'.$value] = $details['value'];
  365. }
  366. $data = array_merge($data,$values_array);
  367. } else {
  368. // no condition? we're doing an INSERT
  369. $data['creation_date'] = time();
  370. $query = "INSERT INTO $q$table_name$q (";
  371. $separator = '';
  372. foreach ($data as $fieldname => $value) {
  373. $query .= $separator.$q.$fieldname.$q;
  374. $separator = ',';
  375. }
  376. $query .= ") VALUES (";
  377. $separator = '';
  378. foreach ($data as $fieldname => $value) {
  379. $query .= $separator.':'.$fieldname;
  380. $separator = ',';
  381. }
  382. $query .= ")";
  383. }
  384. if ($query) {
  385. try {
  386. $q = $this->db->prepare($query);
  387. $success = $q->execute($data);
  388. if ($success) {
  389. if ($conditions) {
  390. if (array_key_exists('id',$conditions)) {
  391. return $conditions['id']['value'];
  392. } else {
  393. return true;
  394. }
  395. } else {
  396. return $this->db->lastInsertId();
  397. }
  398. } else {
  399. return false;
  400. }
  401. } catch(PDOException $e) {
  402. $this->error = $e->getMessage();
  403. error_log('CASHDBA error: ' . $this->error);
  404. }
  405. } else {
  406. return false;
  407. }
  408. } else {
  409. return false;
  410. }
  411. }
  412. public function deleteData($data_name,$conditions=false) {
  413. if (!is_object($this->db)) {
  414. $this->connect();
  415. }
  416. $query = false;
  417. $table_name = $this->lookupTableName($data_name);
  418. if ($conditions) {
  419. $query = "DELETE FROM $table_name" . $this->parseConditions($conditions,false);
  420. try {
  421. $result = $this->db->exec($query);
  422. if ($result) {
  423. return true;
  424. } else {
  425. return false;
  426. }
  427. } catch(PDOException $e) {
  428. $this->error = $e->getMessage();
  429. error_log('CASHDBA error: ' . $this->error);
  430. die();
  431. }
  432. } else {
  433. return false;
  434. }
  435. }
  436. public function getSpecialData($data_name,$conditions=false,$limit=false,$orderby=false) {
  437. if (!is_object($this->db)) {
  438. $this->connect();
  439. }
  440. switch ($data_name) {
  441. case 'AssetPlant_getAnalytics_mostaccessed':
  442. $query = "SELECT aa.asset_id as 'id', COUNT(aa.id) as 'count', a.title as 'title', a.description as 'description' "
  443. . "FROM assets_analytics aa JOIN assets a ON aa.asset_id = a.id "
  444. . "WHERE a.user_id = :user_id AND a.parent_id = 0 "
  445. . "GROUP BY aa.asset_id "
  446. . "ORDER BY count DESC";
  447. break;
  448. case 'AssetPlant_findAssets':
  449. // rough "ranking" in the CASE section below. +2 for query in title, +1 in desc, +1 in metadata
  450. // does not add per-appearance, just on true. slight preference for titles
  451. // exact title matches get an additional +1, titles starting with the query an another +1
  452. $query = "SELECT * FROM assets "
  453. . "WHERE user_id = :user_id AND (title LIKE :query OR description LIKE :query OR metadata LIKE :query) "
  454. . "AND type NOT LIKE 'system%' "
  455. . "AND parent_id = 0 "
  456. . "ORDER BY ("
  457. . "(CASE WHEN title LIKE :query THEN 2 ELSE 0 END) + "
  458. . "(CASE WHEN title LIKE :exact_query THEN 1 ELSE 0 END) + "
  459. . "(CASE WHEN title LIKE :starts_with_query THEN 1 ELSE 0 END) + "
  460. . "(CASE WHEN description LIKE :query THEN 1 ELSE 0 END) + "
  461. . "(CASE WHEN metadata LIKE :query THEN 1 ELSE 0 END) "
  462. . ") DESC, title ASC";
  463. if ($limit) $query .= " LIMIT $limit";
  464. break;
  465. case 'CalendarPlant_findVenues':
  466. // rough "ranking" in the CASE section below. +2 for query in title, +1 in desc, +1 in metadata
  467. // does not add per-appearance, just on true. slight preference for titles
  468. // exact title matches get an additional +1, titles starting with the query an another +1
  469. $query = "SELECT * FROM calendar_venues "
  470. . "WHERE name LIKE :query OR city LIKE :query "
  471. . "ORDER BY ("
  472. . "(CASE WHEN name LIKE :query THEN 2 ELSE 0 END) + "
  473. . "(CASE WHEN city LIKE :query THEN 1 ELSE 0 END)"
  474. . ") DESC, name ASC";
  475. if ($limit) $query .= " LIMIT $limit";
  476. break;
  477. case 'CommercePlant_getOrder_deep':
  478. $query = "SELECT o.id as id, o.user_id as user_id, o.creation_date as creation_date, o.modification_date as modification_date, o.order_contents as order_contents, o.customer_user_id as customer_user_id, o.fulfilled as fulfilled, o.canceled as canceled, o.physical as physical, o.digital as digital, o.country_code as country_code, "
  479. . "t.connection_id as connection_id, t.connection_type as connection_type, t.service_transaction_id as service_transaction_id, t.data_sent as data_sent, t.data_returned as data_returned, t.gross_price as gross_price, t.service_fee as service_fee, t.status as status, t.successful as successful "
  480. . "FROM commerce_orders o JOIN commerce_transactions t ON o.transaction_id = t.id "
  481. . "WHERE o.id = :id ";
  482. break;
  483. case 'CommercePlant_getOrders_deep':
  484. // gets multiple orders with all information
  485. $query = "SELECT o.id as id, o.user_id as user_id, o.creation_date as creation_date, o.modification_date as modification_date, o.order_contents as order_contents, o.customer_user_id as customer_user_id, o.fulfilled as fulfilled, o.canceled as canceled, o.physical as physical, o.digital as digital, o.country_code as country_code, "
  486. . "t.connection_id as connection_id, t.connection_type as connection_type, t.service_transaction_id as service_transaction_id, t.data_sent as data_sent, t.data_returned as data_returned, t.gross_price as gross_price, t.service_fee as service_fee, t.status as status, t.successful as successful "
  487. . "FROM commerce_orders o JOIN commerce_transactions t ON o.transaction_id = t.id "
  488. . "WHERE o.user_id = :user_id AND t.successful = 1";
  489. if (isset($conditions['unfulfilled_only'])) {
  490. if ($conditions['unfulfilled_only']['value'] == 1) {
  491. $query .= " AND o.fulfilled < :unfulfilled_only";
  492. } else {
  493. $query .= " AND o.fulfilled >= :unfulfilled_only";
  494. }
  495. }
  496. if ($limit) $query .= " LIMIT $limit";
  497. break;
  498. case 'CommercePlant_getAnalytics_transactions':
  499. $query = "SELECT SUM(gross_price) AS total_gross, COUNT(id) AS total_transactions "
  500. . "FROM commerce_transactions "
  501. . "WHERE user_id = :user_id AND successful = 1 AND creation_date > :date_low AND creation_date < :date_high";
  502. break;
  503. case 'ElementPlant_getAnalytics_mostactive':
  504. $query = "SELECT ea.element_id as 'id', COUNT(ea.id) as 'count', e.name as 'name' "
  505. . "FROM elements_analytics ea JOIN elements e ON ea.element_id = e.id "
  506. . "WHERE e.user_id = :user_id AND ea.access_time > " . (time() - 1209600) . " " // active == used in the last 2 weeks
  507. . "GROUP BY ea.element_id "
  508. . "ORDER BY count DESC";
  509. break;
  510. case 'ElementPlant_getCampaignForElement':
  511. $query = "SELECT * FROM elements_campaigns "
  512. . "WHERE elements LIKE :elements1 OR elements LIKE :elements2 OR elements LIKE :elements3 "
  513. . "OR elements LIKE :elements4 OR elements LIKE :elements5 OR elements LIKE :elements6";
  514. break;
  515. case 'PeoplePlant_getAnalytics_listmembership':
  516. $query = "SELECT COUNT(*) AS total, COUNT(CASE WHEN active = 1 THEN 1 END) AS active, COUNT(CASE WHEN active = 0 THEN 1 END) AS inactive, COUNT(CASE WHEN creation_date > " . (time() - 604800) . " THEN 1 END) AS last_week "
  517. . "FROM people_lists_members "
  518. . "WHERE list_id = :list_id";
  519. break;
  520. case 'PeoplePlant_getContactInitials':
  521. $query = "SELECT DISTINCT UPPER(SUBSTR(last_name,1,1)) as 'initial' FROM people_contacts "
  522. . "WHERE user_id = :user_id ORDER BY last_name";
  523. break;
  524. case 'PeoplePlant_getUsersForList':
  525. $query = "SELECT u.id,u.email_address,u.display_name,u.first_name,u.last_name,"
  526. . "l.initial_comment,l.additional_data,l.active,l.verified,l.creation_date "
  527. . "FROM people u LEFT OUTER JOIN people_lists_members l ON u.id = l.user_id "
  528. . "WHERE l.list_id = :list_id AND l.active = 1";
  529. if ($orderby) $query .= " ORDER BY $orderby";
  530. if ($limit) $query .= " LIMIT $limit";
  531. break;
  532. case 'PeoplePlant_getRecentActivity':
  533. $query = "SELECT DISTINCT m.list_id AS 'list_id', l.name as 'name', COUNT(m.list_id) AS 'total' "
  534. . "FROM people_lists_members m "
  535. . "INNER JOIN people_lists l ON m.list_id = l.id "
  536. . "WHERE l.user_id = :user_id AND m.active = 1 AND m.creation_date > :since_date "
  537. . "GROUP BY m.list_id ";
  538. break;
  539. case 'PeoplePlant_getVerifiedUsersForList':
  540. $query = "SELECT u.id,u.email_address,u.display_name,"
  541. . "l.initial_comment,l.additional_data,l.creation_date "
  542. . "FROM people u LEFT OUTER JOIN people_lists_members l ON u.id = l.user_id "
  543. . "WHERE l.list_id = :list_id AND l.verified = 1 AND l.active = 1";
  544. if ($orderby) $query .= " ORDER BY $orderby";
  545. if ($limit) $query .= " LIMIT $limit";
  546. break;
  547. case 'CalendarPlant_getDatesBetween':
  548. $query = "SELECT e.id as 'event_id', e.date as 'date',e.published as 'published',e.cancelled as 'cancelled',e.purchase_url as 'purchase_url',e.comments as 'comments',e.creation_date as 'creation_date',e.modification_date as 'modification_date', "
  549. . "v.name as 'venue_name',v.address1 as 'venue_address1',v.address2 as 'venue_address2',v.city 'venue_city',v.region as 'venue_region',v.country as 'venue_country',v.postalcode as 'venue_postalcode',v.url as 'venue_url',v.phone as 'venue_phone'"
  550. . "FROM calendar_events e LEFT OUTER JOIN calendar_venues v ON e.venue_id = v.id "
  551. . "WHERE e.date > :cutoff_date_low AND e.date < :cutoff_date_high AND e.user_id = :user_id AND e.published = :published_status AND e.cancelled = :cancelled_status ORDER BY e.date ASC";
  552. break;
  553. case 'CalendarPlant_getEvent':
  554. $query = "SELECT e.id as 'event_id', e.user_id as 'user_id', e.date as 'date',e.published as 'published',e.cancelled as 'cancelled',e.purchase_url as 'purchase_url',e.comments as 'comments',e.creation_date as 'creation_date',e.modification_date as 'modification_date', "
  555. . "v.id as 'venue_id',v.name as 'venue_name',v.address1 as 'venue_address1',v.address2 as 'venue_address2',v.city 'venue_city',v.region as 'venue_region',v.country as 'venue_country',v.postalcode as 'venue_postalcode',v.url as 'venue_url',v.phone as 'venue_phone'"
  556. . "FROM calendar_events e LEFT OUTER JOIN calendar_venues v ON e.venue_id = v.id "
  557. . "WHERE e.id = :event_id LIMIT 1";
  558. break;
  559. default:
  560. return false;
  561. }
  562. if ($query) {
  563. if ($conditions) {
  564. $values_array = array();
  565. foreach ($conditions as $value => $details) {
  566. $values_array[':'.$value] = $details['value'];
  567. }
  568. return $this->doQuery($query,$values_array);
  569. } else {
  570. return $this->doQuery($query);
  571. }
  572. } else {
  573. return false;
  574. }
  575. }
  576. } // END class
  577. ?>