/** * Build the query and his PDO statement with SQL infos already set to this object * @return bool */ public function buildQuery($forceRebuild = FALSE) { if (!isset($this->_SQL['stmt']) || $forceRebuild) { /* exec query once a page load */ \app::dispatchEvent('beforeBuildQuery', array()); /* SELECT */ $query = 'SELECT '; if ($this instanceof \entity) { /* only for entity, to define defaults selects && from */ $this->beforeSelect(); if (empty($this->_SQL['selects'])) { $this->_SQL['selects'][$this->_tableName . '.*'] = $this->_tableName . '.*'; } $this->_SQL['froms'][$this->_tableName] = $this->_tableName; /* FROM for entity */ /* extends */ if (!empty($this->_extends)) { foreach ($this->_extends as $entity) { $foreignFields = $entity->getFields(); foreach ($foreignFields as $name => &$field) { if ($name !== $field->name) { /* detect alias */ $tableName = $field->getTableName(); $aliasName = $name . '_' . $tableName; $this->_SQL['selects'][$aliasName] = $tableName . '.' . $name . ' AS ' . $aliasName; } else { $this->_SQL['selects'][$name] = $field->getTableName() . '.' . $name; /* best than "table.*" which bug when using alias ( duplicate) */ } } $foreignTableName = str_replace('\\model\\', '_', get_class($entity)); $this->join($this->_tableName . '.' . $this->getId()->name, $foreignTableName . '.' . $entity->getId()->name, 'left outer join'); } } } foreach ($this->getFields() as $field) { /* TODO IMPROVE */ if (!$field instanceof \core\fields\alias) { $module = $field->entity->getModule(); $entity = $field->entity->getName(); $id = $field->entity->getId()->name; if ($field instanceof \field_formasso) { $cutForeign = explode('_', $field->entity_foreign, 2); $foreignEntity = \app::getModule($cutForeign[0])->getEntity($cutForeign[1]); $idNameForeignEntity = $foreignEntity->getId()->name; $this->_SQL['selects'][$field->name] = ' CONCAT( \'{\', GROUP_CONCAT(CONCAT(\'"\', ' . $field->entity_foreign . '.' . $idNameForeignEntity . ' , \'"\',\':"\',' . $field->entity_foreign . '.' . $foreignEntity->getBehaviorTitle() . ', \'"\')), \'}\') AS ' . $field->name; $this->groupBy($module . '_' . $entity . '.' . $id); $this->join($module . '_' . $entity . '.' . $id, $field->entity_asso . '.' . $field->entity->getId()->name, 'left outer join'); $this->join($field->entity_asso . '.' . $idNameForeignEntity, $field->entity_foreign . '.' . $idNameForeignEntity, 'left outer join'); } elseif ($this->getField($id) === FALSE) { $this->select($module . '_' . $entity . '.' . $id, TRUE); } } } $query .= implode(',', $this->_SQL['selects']); /* FROM */ if (empty($this->_SQL['joins'])) { $query .= ' FROM ' . reset($this->_SQL['froms']); } else { $firstTable = reset($this->_SQL['joins']); $tableLeft = strstr($firstTable['propertyLeft'], '.', true); $query .= ' FROM ' . $tableLeft; $this->_SQL['froms'][$tableLeft] = $tableLeft; //to prefix $tableLeft foreach ($this->_SQL['joins'] as $join) { $tableRight = strstr($join['propertyRight'], '.', true); $this->_SQL['froms'][$tableRight] = $tableRight; //to prefix $tableRight $query .= ' ' . $join['type'] . ' ' . $tableRight . ' ON ' . $join['propertyLeft'] . ' = ' . $join['propertyRight']; } } /* WHERE */ $this->_SQL['vars'] = array(); // init here for pagination if (isset($this->_SQL['wheres'])) { $wheres = array(); foreach ($this->_SQL['wheres'] as $where) { // Frame the "where" if several sql conditions /* For the record if(strstr($where,'&&') || strstr($where,'||') || stristr($where,' or ') || stristr($where,' and ')) $wheres[] = */ $wheres[] = '(' . $this->evaluateConditions($where) . ')'; } if (!empty($wheres)) { $query .= ' WHERE ' . implode(' AND ', $wheres); } } /* GROUP BY */ if (isset($this->_SQL['groupBys'])) { $query .= ' GROUP BY ' . implode(' ,', $this->_SQL['groupBys']); } /* HAVING */ if (isset($this->_SQL['havings'])) { $havings = array(); foreach ($this->_SQL['havings'] as $having) { // Frame the "having" if several sql conditions $havings[] = '(' . $this->evaluateConditions($having) . ')'; } if (!empty($havings)) { $query .= ' HAVING ' . implode(' AND ', $havings); } } /* ORDER */ if (isset($this->_SQL['orders'])) { $orders = array(); foreach ($this->_SQL['orders'] as $property => $order) { $orders[] = $property . ' ' . $order; } $query .= ' ORDER BY ' . implode(',', $orders); } /* DB PREFIX */ if (PREFIX !== '') { /* must be before pagination */ $query .= ' '; /* tip to replace table name */ foreach ($this->_SQL['froms'] as $table) { $query = preg_replace('/([,\\s\\(])' . $table . '([\\.\\s])/', '$1' . PREFIX . $table . '$2', $query); } } /* LIMIT */ if (isset($this->_SQL['limit'])) { $limit = ' LIMIT 0,' . $this->_SQL['limit']; if (isset($this->_SQL['pagination']) && $this->_SQL['pagination'] !== FALSE) { $this->_SQL['pagination'] = new \pagination($query, $this->_SQL['limit'], $this->_SQL['vars']); $start = $this->_SQL['pagination']->getCurrentPage() * $this->_SQL['limit'] - $this->_SQL['limit']; $limit = ' LIMIT ' . $start . ',' . $this->_SQL['limit']; } $query .= $limit; } $this->_SQL['query'] = $query; } /* EXEC query */ if (!empty($this->_SQL['vars'])) { $this->_SQL['stmt'] = \PDOconnection::getDB()->prepare($this->_SQL['query']); $this->_SQL['stmt']->setFetchMode(\PDO::FETCH_INTO, $this); $this->_SQL['stmt']->execute($this->_SQL['vars']); } else { $this->_SQL['stmt'] = \PDOconnection::getDB()->query($this->_SQL['query'], \PDO::FETCH_INTO, $this); } return $this->_SQL['stmt']; }
public function __wakeup() { /* Get fields and separate them from other props */ $fields = get_object_vars($this); foreach ($fields as $name => &$property) { if ($property instanceof \field) { /* Insert an entity reference in each field */ $property->setEntity($this); /* Save field in fields array - usefull to extend(), getFields(), getId() methods, also idem to class view structure */ $this->fields[$name] = $property; } } \app::dispatchEvent('wakeupEntity', array($this->_tableName, &$this)); /* mainly if antoher module wants to extend this entity */ }
/** * Send content to client * @param mixed $body optional */ public function setContent($body = '', $status = FALSE) { if ($status !== FALSE) { $this->setStatus($status); } if ($body instanceof page) { /* If it's a page object */ $this->page = $body; /* Save page object */ /* Init defaults JS and CSS for CMS pages */ $this->addJSFile('core/js/parsimony.js'); $this->addCSSFile('core/css/parsimony.css'); \app::dispatchEvent('beforePageLoad'); $theme = $this->page->getTheme(); if ($theme instanceof theme) { define('THEMEMODULE', $theme->getModule()); define('THEME', $theme->getName()); $this->addCSSFile(THEMEMODULE . '/themes/' . THEME . '/style.css'); $body = $theme->display(); /* Display with theme */ } else { define('THEMEMODULE', ''); define('THEME', ''); $body = $body->display(); /* Display without theme */ } /* Set page infos to admin */ if (!defined('PARSI_ADMIN') && $_SESSION['permissions'] > 0 && \app::$request->getParam('popup') !== '') { $timer = isset($_SERVER['REQUEST_TIME_FLOAT']) ? round(microtime(true) - $_SERVER['REQUEST_TIME_FLOAT'], 4) : '~ ' . floor(microtime(true) - $_SERVER['REQUEST_TIME']); /* Be sure that editiniline can be used in edit mode */ \app::$response->addJSFile('core/js/editinline.js'); \app::$response->addCSSFile('core/css/editinline.css'); /* correct resMax with preview screen */ \app::$response->head .= '<script>document.cookie = "DW=" + (top.ParsimonyAdmin.getCookie("screenX") || screen.width) + ";path=/";document.cookie = "DH=" + (top.ParsimonyAdmin.getCookie("screenY") || screen.height) + ";path=/";</script>'; $body .= '<script>top.document.getElementById("infodev_timer").textContent="' . $timer . ' s";top.document.getElementById("infodev_module").textContent="' . MODULE . '";top.document.getElementById("infodev_theme").textContent="' . THEME . '";top.setActiveTheme("' . THEME . '");top.document.getElementById("infodev_page").textContent="' . $this->page->getId() . '";'; $pathTheme = THEMEMODULE . '/themes/' . THEME . '/style.css'; if ($_SESSION['permissions'] & 16) { /* Store on client side all CSS selectors from theme style */ $css = new css(stream_resolve_include_path($pathTheme)); $CSSValues = $css->getCSSValues(); $body .= 'top.Parsimony.blocks["admin_css"].CSSValues["' . $pathTheme . '"] = ' . json_encode($CSSValues) . ';'; } $body .= 'top.history.replaceState({url:document.location.pathname}, document.title, document.location.pathname.replace("?preview=ok","").replace("preview=ok",""));top.$_GET=' . json_encode($_GET) . ';top.$_POST=' . json_encode($_POST) . ';top.CSSTHEMEPATH = "' . $pathTheme . '";top.CSSPAGEPATH = "' . MODULE . '/css/' . DEVICE . '.css";document.addEventListener("DOMContentLoaded", function() {top.ParsimonyAdmin.initPreview();}); </script>'; } \app::dispatchEvent('afterPageLoad'); /* Wrap body with HTML structure */ ob_start(); include 'core/views/index.php'; $body = ob_get_clean(); \app::dispatchEvent('beforePageDisplay', array(&$body)); /* allow to process files before they are sent to the client */ } /* Set headers */ header($_SERVER['SERVER_PROTOCOL'] . ' ' . $this->status . ' ' . self::$HTTPstatus[$this->status], true, $this->status); header('Content-type: ' . \app::$config['ext'][$this->format] . '; charset=' . $this->charset); header('Vary: User-Agent'); /* Dynamically serving different HTML on the same URL */ foreach ($this->headers as $label => $header) { header($label . ': ' . $header); } /* Set body to client */ $this->body = $body; }