Created
November 26, 2013 17:47
-
-
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)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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