|
|
@@ -1674,7 +1674,7 @@ class Table implements RepositoryInterface, EventListenerInterface, EventDispatc
|
|
|
* transaction (default: true)
|
|
|
* - defaults: Whether to use the search criteria as default values for the new entity (default: true)
|
|
|
*
|
|
|
- * @param array|\Cake\ORM\Query $search The criteria to find existing
|
|
|
+ * @param array|callable|\Cake\ORM\Query $search The criteria to find existing
|
|
|
* records by. Note that when you pass a query object you'll have to use
|
|
|
* the 2nd arg of the method to modify the entity data before saving.
|
|
|
* @param callable|null $callback A callback that will be invoked for newly
|
|
|
@@ -1704,7 +1704,7 @@ class Table implements RepositoryInterface, EventListenerInterface, EventDispatc
|
|
|
/**
|
|
|
* Performs the actual find and/or create of an entity based on the passed options.
|
|
|
*
|
|
|
- * @param array|callable $search The criteria to find an existing record by, or a callable tha will
|
|
|
+ * @param array|callable|\Cake\ORM\Query $search The criteria to find an existing record by, or a callable tha will
|
|
|
* customize the find query.
|
|
|
* @param callable|null $callback A callback that will be invoked for newly
|
|
|
* created entities. This callback will be called *before* the entity
|
|
|
@@ -1714,20 +1714,12 @@ class Table implements RepositoryInterface, EventListenerInterface, EventDispatc
|
|
|
*/
|
|
|
protected function _processFindOrCreate($search, callable $callback = null, $options = [])
|
|
|
{
|
|
|
- if (is_callable($search)) {
|
|
|
- $query = $this->find();
|
|
|
- $search($query);
|
|
|
- } elseif (is_array($search)) {
|
|
|
- $query = $this->find()->where($search);
|
|
|
- } elseif ($search instanceof Query) {
|
|
|
- $query = $search;
|
|
|
- } else {
|
|
|
- throw new InvalidArgumentException('Search criteria must be an array, callable or Query');
|
|
|
- }
|
|
|
+ $query = $this->_getFindOrCreateQuery($search);
|
|
|
$row = $query->first();
|
|
|
if ($row !== null) {
|
|
|
return $row;
|
|
|
}
|
|
|
+
|
|
|
$entity = $this->newEntity();
|
|
|
if ($options['defaults'] && is_array($search)) {
|
|
|
$entity->set($search, ['guard' => false]);
|
|
|
@@ -1743,16 +1735,23 @@ class Table implements RepositoryInterface, EventListenerInterface, EventDispatc
|
|
|
/**
|
|
|
* Gets the query object for findOrCreate().
|
|
|
*
|
|
|
- * @param array|\Cake\ORM\Query|string $search The criteria to find existing records by.
|
|
|
+ * @param array|callable|\Cake\ORM\Query $search The criteria to find existing records by.
|
|
|
* @return \Cake\ORM\Query
|
|
|
*/
|
|
|
protected function _getFindOrCreateQuery($search)
|
|
|
{
|
|
|
- if ($search instanceof Query) {
|
|
|
- return $search;
|
|
|
+ if (is_callable($search)) {
|
|
|
+ $query = $this->find();
|
|
|
+ $search($query);
|
|
|
+ } elseif (is_array($search)) {
|
|
|
+ $query = $this->find()->where($search);
|
|
|
+ } elseif ($search instanceof Query) {
|
|
|
+ $query = $search;
|
|
|
+ } else {
|
|
|
+ throw new InvalidArgumentException('Search criteria must be an array, callable or Query');
|
|
|
}
|
|
|
|
|
|
- return $this->find()->where($search);
|
|
|
+ return $query;
|
|
|
}
|
|
|
|
|
|
/**
|