Skip to content

Instantly share code, notes, and snippets.

@patrickmaciel
Created November 26, 2013 17:47
Show Gist options
  • Save patrickmaciel/7662749 to your computer and use it in GitHub Desktop.
Save patrickmaciel/7662749 to your computer and use it in GitHub Desktop.
Modifications in CakePHP core for work with composite primary keys (not a bad pratice but, some of your customers maybe use this)
diff --git a/app/Config/bootstrap.php b/app/Config/bootstrap.php
index 3fc6685..1966994 100644
--- a/app/Config/bootstrap.php
+++ b/app/Config/bootstrap.php
@@ -28,14 +28,10 @@ require_once APP . 'Vendor' . DS . 'autoload.php';
// Setup a 'default' cache configuration for use in the application.
Cache::config('default', array('engine' => 'File'));
-// CakeLog::config('otherFile', array(
-// 'engine' => 'DatabaseLogger',
-// 'model' => 'LogEntry'
-// ));
@@ -109,13 +106,13 @@ Configure::write('Dispatcher.filters', array(
* Configures default file logging options
*/
App::uses('CakeLog', 'Log');
-CakeLog::config('debug', array(
- 'engine' => 'FileLog',
- 'types' => array('notice', 'info', 'debug'),
- 'file' => 'debug',
-));
-CakeLog::config('error', array(
- 'engine' => 'FileLog',
- 'types' => array('warning', 'error', 'critical', 'alert', 'emergency'),
- 'file' => 'error',
-));
+// CakeLog::config('debug', array(
+// 'engine' => 'FileLog',
+// 'types' => array('notice', 'info', 'debug'),
+// 'file' => 'debug',
+// ));
+// CakeLog::config('error', array(
+// 'engine' => 'FileLog',
+// 'types' => array('warning', 'error', 'critical', 'alert', 'emergency'),
+// 'file' => 'error',
+// ));
diff --git a/app/Model/AppModel.php b/app/Model/AppModel.php
index de243e1..c9b4c67 100644
--- a/app/Model/AppModel.php
+++ b/app/Model/AppModel.php
@@ -22,6 +22,7 @@
*/
App::uses('Model', 'Model');
+App::uses('AuditableConfig', 'Auditable.Lib');
/**
* Application model for Cake.
@@ -35,26 +36,32 @@ class AppModel extends Model {
public $cacheQueries = false;
+ public function __construct($id = false, $table = null, $ds = null) {
+ if(get_class($this) !== 'Logger' && empty(AuditableConfig::$Logger)) {
+ // Caso deseje usar o modelo padrão, utilize como abaixo, caso contrário você pode usar qualquer modelo
+ AuditableConfig::$Logger = ClassRegistry::init('Auditable.Logger', true);
+ }
+
+ parent::__construct($id, $table, $ds);
+ }
+
public function lastquery() {
- $dbo = $this->getDatasource();
- $logs = $dbo->getLog();
- $lastLog = end($logs['log']);
- return $lastLog['query'];
+ $dbo = $this->getDatasource();
+ $logs = $dbo->getLog();
+ $lastLog = end($logs['log']);
+ return $lastLog['query'];
}
public function allqueries() {
- $dbo = $this->getDatasource();
- $logs = $dbo->getLog();
- return $logs['log'];
+ $dbo = $this->getDatasource();
+ $logs = $dbo->getLog();
+ return $logs['log'];
}
public function nextval($sequence) {
-
- $sql = "select nextval('" . $sequence . "') as nextval;";
- $nextval = $this->query($sql, false);
-
- return $nextval[0][0]['nextval'];
-
+ $sql = "select nextval('" . $sequence . "') as nextval;";
+ $nextval = $this->query($sql, false);
+ return $nextval[0][0]['nextval'];
}
}
diff --git a/app/Plugin/Auditable/Controller/LoggersController.php b/app/Plugin/Auditable/Controller/LoggersController.php
new file mode 100644
index 0000000..e63223a
--- /dev/null
+++ b/app/Plugin/Auditable/Controller/LoggersController.php
@@ -0,0 +1,35 @@
+<?php
+/**
+ * Controller de exemplo para consultar os logs registrados, juntamente
+ * com o Helper Auditor.
+ *
+ * PHP version > 5.3.1
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Radig - Soluções em TI, www.radig.com.br
+ * @link http://www.radig.com.br
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ *
+ * @package radig.Auditable
+ * @subpackage Controller
+ */
+class LoggersController extends AppController
+{
+ public $helpers = array('Auditable.Auditor');
+
+ public function index() {
+ $this->set('loggers', $this->paginate());
+ }
+
+ public function view($id) {
+ $this->Logger->id = $id;
+
+ if(!$this->Logger->exists()) {
+ throw new NotFoundException(__d('auditable', 'Log entry could not be find.'));
+ }
+
+ $this->set('logger', $this->Logger->get($id));
+ }
+}
diff --git a/lib/Cake/Model/Datasource/DboSource.php b/lib/Cake/Model/Datasource/DboSource.php
index abdad24..1227d08 100644
--- a/lib/Cake/Model/Datasource/DboSource.php
+++ b/lib/Cake/Model/Datasource/DboSource.php
@@ -1002,12 +1002,35 @@ class DboSource extends DataSource {
);
if ($this->execute($this->renderStatement('create', $query))) {
- if (empty($id)) {
- $id = $this->lastInsertId($this->fullTableName($model, false, false), $model->primaryKey);
- }
- $model->setInsertID($id);
- $model->id = $id;
+ if ($model->primaryKey !== false) {
+ if (empty($id)) {
+ $id = $this->lastInsertId($this->fullTableName($model, false, false), $model->primaryKey);
+ }
+ $model->setInsertID($id);
+ $model->id = $id;
+ } else if ($model->primaryKey === false) {
+
+ // If the current model you have multiple primary keys,
+ // The following code will fetch these primary keys
+ // informed in the corresponding array Model:$multiplePrimaryKey
+ //
+ // After this, the primary keys that were found are set in the Model
+ if (is_array($model->multiplePrimaryKey) && (count($model->multiplePrimaryKey) > 0)) {
+ $ids = array();
+ foreach($model->multiplePrimaryKey as $mpk) {
+ if (isset($model->data[$model->alias][$mpk])) {
+ $ids["$mpk"] = $model->data[$model->alias][$mpk];
+ }
+ }
+
+ if (is_array($ids) && (count($ids) > 0)) {
+ $model->ids = $ids;
+ }
+ }
+ }
+
return true;
+
}
$model->onError();
return false;
@@ -1827,6 +1850,7 @@ class DboSource extends DataSource {
$alias = $joins = null;
$table = $this->fullTableName($model);
+
$conditions = $this->_matchRecords($model, $conditions);
if ($conditions === false) {
@@ -1943,8 +1967,8 @@ class DboSource extends DataSource {
}
}
if ($noJoin === true) {
- return $this->conditions($conditions);
- }
+ return $this->conditions($conditions);
+ }
$idList = $model->find('all', array(
'fields' => "{$model->alias}.{$model->primaryKey}",
'conditions' => $conditions
@@ -2206,6 +2230,17 @@ class DboSource extends DataSource {
if (!$useAlias) {
$alias = $this->fullTableName($model, false);
}
+
+ $id = $model->getID();
+ if (is_array($id) and (count($id) > 0)) {
+ $multiple_conditions = array();
+ foreach($id as $key => $mpk) {
+ $multiple_conditions[$alias . '.' . $key] = $mpk;
+ }
+
+ return $multiple_conditions;
+ }
+
return array("{$alias}.{$model->primaryKey}" => $model->getID());
}
diff --git a/lib/Cake/Model/Model.php b/lib/Cake/Model/Model.php
index 6362166..a1495f1 100644
--- a/lib/Cake/Model/Model.php
+++ b/lib/Cake/Model/Model.php
@@ -1515,17 +1515,45 @@ class Model extends Object implements CakeEventListener {
$id = $this->id;
- if (is_array($this->id)) {
+ if (is_array($this->id) AND isset($this->id[0])) {
$id = $this->id[0];
- }
+ } else if (is_array($this->id)) {
+ // If has informed in id an array with key => value reference
+ // the multiplePrimarykey array in the Model
+ foreach($this->id as $key => $mpk) {
+ $id[$key] = $mpk;
+ }
+ }
+
+ if ($id !== null && $id !== false && !is_array($id)) {
- if ($id !== null && $id !== false) {
$this->data = $this->find('first', array(
'conditions' => array($this->alias . '.' . $this->primaryKey => $id),
'fields' => $fields
));
return $this->data;
- }
+
+ } else if (
+ $id !== null &&
+ $id !== false &&
+ is_array($id) &&
+ (is_array($this->multiplePrimaryKey) && (count($this->multiplePrimaryKey) > 0))
+ ) {
+
+ $conditions = array();
+ foreach($this->multiplePrimaryKey as $mpk) {
+ $conditions[$this->alias . '.' . $mpk] = $id[$mpk];
+ }
+
+ $this->data = $this->find('first', array(
+ 'conditions' => $conditions,
+ 'fields' => $fields
+ ));
+
+ return $this->data;
+
+ }
+
return false;
}
@@ -1691,9 +1719,27 @@ class Model extends Object implements CakeEventListener {
$db = $this->getDataSource();
- if (empty($this->data[$this->alias][$this->primaryKey])) {
+ if ($this->primaryKey !== false && empty($this->data[$this->alias][$this->primaryKey])) {
+
unset($this->data[$this->alias][$this->primaryKey]);
- }
+
+ } else if(
+ $this->primaryKey === false &&
+ (
+ isset($this->multiplePrimaryKey) &&
+ is_array($this->multiplePrimaryKey) &&
+ (count($this->multiplePrimaryKey) > 0)
+ )
+ ) {
+
+ foreach($this->multiplePrimaryKey as $mpk) {
+ if(empty($this->data[$this->alias][$mpk])) {
+ unset($this->data[$this->alias][$mpk]);
+ }
+ }
+
+ }
+
$fields = $values = array();
foreach ($this->data as $n => $v) {
@@ -1728,8 +1774,7 @@ class Model extends Object implements CakeEventListener {
if ($count > 0) {
$cache = $this->_prepareUpdateFields(array_combine($fields, $values));
-
- if (!empty($this->id)) {
+ if (!empty($this->id)) {
$success = (bool)$db->update($this, $fields, $values);
} else {
if (empty($this->data[$this->alias][$this->primaryKey]) && $this->_isUUIDField($this->primaryKey)) {
@@ -1789,8 +1834,12 @@ class Model extends Object implements CakeEventListener {
* @return boolean
*/
protected function _isUUIDField($field) {
- $field = $this->schema($field);
- return $field['length'] == 36 && in_array($field['type'], array('string', 'binary'));
+ $field = $this->schema($field);
+ if (isset($field['length'])) {
+ return $field['length'] == 36 && in_array($field['type'], array('string', 'binary'));
+ } else {
+ return false;
+ }
}
/**
@@ -2597,13 +2646,32 @@ class Model extends Object implements CakeEventListener {
if ($id === false) {
return false;
}
- return (bool)$this->find('count', array(
- 'conditions' => array(
- $this->alias . '.' . $this->primaryKey => $id
- ),
- 'recursive' => -1,
- 'callbacks' => false
- ));
+
+ if (is_array($id) and (count($id) > 0)) {
+
+ $multiple_conditions = array();
+ foreach($id as $key => $mpk) {
+ $multiple_conditions[$this->alias . '.' . $key] = $mpk;
+ }
+
+ return (bool)$this->find('count', array(
+ 'conditions' => $multiple_conditions,
+ 'recursive' => -1,
+ 'callbacks' => false
+ ));
+
+ } else {
+
+ return (bool)$this->find('count', array(
+ 'conditions' => array(
+ $this->alias . '.' . $this->primaryKey => $id
+ ),
+ 'recursive' => -1,
+ 'callbacks' => false
+ ));
+
+ }
+
}
/**
@@ -3143,6 +3211,24 @@ class Model extends Object implements CakeEventListener {
* @return mixed The ID of the current record, false if no ID
*/
public function getID($list = 0) {
+
+ // Verifying if multiple primary keys has informed
+ // in save or update actions
+ if (
+ (is_array($this->id) OR empty($this->id)) &&
+ isset($this->ids) &&
+ is_array($this->ids) &&
+ (count($this->ids) > 0) &&
+ isset($this->multiplePrimaryKey)
+ ) {
+ $ids = array();
+ foreach($this->multiplePrimaryKey as $mpk) {
+ $ids[$mpk] = $this->data[$this->alias][$mpk];
+ }
+
+ return $ids;
+ }
+
if (empty($this->id) || (is_array($this->id) && isset($this->id[0]) && empty($this->id[0]))) {
return false;
}
@@ -3151,7 +3237,7 @@ class Model extends Object implements CakeEventListener {
}
if (isset($this->id[$list]) && !empty($this->id[$list])) {
return $this->id[$list];
- }
+ }
if (isset($this->id[$list])) {
return false;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment