CakePHP
  • Documentation
    • Book
    • API
    • Videos
    • Logos & Trademarks
  • Business Solutions
  • Swag
  • Road Trip
  • Team
  • Community
    • Community
    • Team
    • Issues (Github)
    • YouTube Channel
    • Get Involved
    • Bakery
    • Featured Resources
    • Newsletter
    • Certification
    • My CakePHP
    • CakeFest
    • Facebook
    • Twitter
    • Help & Support
    • Forum
    • Stack Overflow
    • IRC
    • Slack
    • Paid Support
CakePHP

C CakePHP 3.7 Red Velvet API

  • Overview
  • Tree
  • Deprecated
  • Version:
    • 3.7
      • 3.7
      • 3.6
      • 3.5
      • 3.4
      • 3.3
      • 3.2
      • 3.1
      • 3.0
      • 2.10
      • 2.9
      • 2.8
      • 2.7
      • 2.6
      • 2.5
      • 2.4
      • 2.3
      • 2.2
      • 2.1
      • 2.0
      • 1.3
      • 1.2

Namespaces

  • Cake
    • Auth
      • Storage
    • Cache
      • Engine
    • Collection
      • Iterator
    • Command
    • Console
      • Exception
    • Controller
      • Component
      • Exception
    • Core
      • Configure
        • Engine
      • Exception
      • Retry
    • Database
      • Driver
      • Exception
      • Expression
      • Schema
      • Statement
      • Type
    • Datasource
      • Exception
    • Error
      • Middleware
    • Event
      • Decorator
    • Filesystem
    • Form
    • Http
      • Client
        • Adapter
        • Auth
      • Cookie
      • Exception
      • Middleware
      • Session
    • I18n
      • Formatter
      • Middleware
      • Parser
    • Log
      • Engine
    • Mailer
      • Exception
      • Transport
    • Network
      • Exception
    • ORM
      • Association
      • Behavior
        • Translate
      • Exception
      • Locator
      • Rule
    • Routing
      • Exception
      • Filter
      • Middleware
      • Route
    • Shell
      • Helper
      • Task
    • TestSuite
      • Fixture
      • Stub
    • Utility
      • Exception
    • Validation
    • View
      • Exception
      • Form
      • Helper
      • Widget
  • None

Classes

  • Association
  • AssociationCollection
  • Behavior
  • BehaviorRegistry
  • EagerLoader
  • Entity
  • Marshaller
  • Query
  • ResultSet
  • RulesChecker
  • SaveOptionsBuilder
  • Table
  • TableRegistry

Interfaces

  • PropertyMarshalInterface

Traits

  • AssociationsNormalizerTrait
  1: <?php
  2: /**
  3:  * CakePHP(tm) : Rapid Development Framework (https://cakephp.org)
  4:  * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
  5:  *
  6:  * Licensed under The MIT License
  7:  * For full copyright and license information, please see the LICENSE.txt
  8:  * Redistributions of files must retain the above copyright notice.
  9:  *
 10:  * @copyright     Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
 11:  * @link          https://cakephp.org CakePHP(tm) Project
 12:  * @since         3.0.0
 13:  * @license       https://opensource.org/licenses/mit-license.php MIT License
 14:  */
 15: namespace Cake\ORM;
 16: 
 17: use ArrayIterator;
 18: use Cake\Datasource\EntityInterface;
 19: use Cake\ORM\Locator\LocatorAwareTrait;
 20: use Cake\ORM\Locator\LocatorInterface;
 21: use InvalidArgumentException;
 22: use IteratorAggregate;
 23: 
 24: /**
 25:  * A container/collection for association classes.
 26:  *
 27:  * Contains methods for managing associations, and
 28:  * ordering operations around saving and deleting.
 29:  */
 30: class AssociationCollection implements IteratorAggregate
 31: {
 32: 
 33:     use AssociationsNormalizerTrait;
 34:     use LocatorAwareTrait;
 35: 
 36:     /**
 37:      * Stored associations
 38:      *
 39:      * @var \Cake\ORM\Association[]
 40:      */
 41:     protected $_items = [];
 42: 
 43:     /**
 44:      * Constructor.
 45:      *
 46:      * Sets the default table locator for associations.
 47:      * If no locator is provided, the global one will be used.
 48:      *
 49:      * @param \Cake\ORM\Locator\LocatorInterface|null $tableLocator Table locator instance.
 50:      */
 51:     public function __construct(LocatorInterface $tableLocator = null)
 52:     {
 53:         if ($tableLocator !== null) {
 54:             $this->_tableLocator = $tableLocator;
 55:         }
 56:     }
 57: 
 58:     /**
 59:      * Add an association to the collection
 60:      *
 61:      * If the alias added contains a `.` the part preceding the `.` will be dropped.
 62:      * This makes using plugins simpler as the Plugin.Class syntax is frequently used.
 63:      *
 64:      * @param string $alias The association alias
 65:      * @param \Cake\ORM\Association $association The association to add.
 66:      * @return \Cake\ORM\Association The association object being added.
 67:      */
 68:     public function add($alias, Association $association)
 69:     {
 70:         list(, $alias) = pluginSplit($alias);
 71: 
 72:         return $this->_items[strtolower($alias)] = $association;
 73:     }
 74: 
 75:     /**
 76:      * Creates and adds the Association object to this collection.
 77:      *
 78:      * @param string $className The name of association class.
 79:      * @param string $associated The alias for the target table.
 80:      * @param array $options List of options to configure the association definition.
 81:      * @return \Cake\ORM\Association
 82:      * @throws \InvalidArgumentException
 83:      */
 84:     public function load($className, $associated, array $options = [])
 85:     {
 86:         $options += [
 87:             'tableLocator' => $this->getTableLocator()
 88:         ];
 89: 
 90:         $association = new $className($associated, $options);
 91:         if (!$association instanceof Association) {
 92:             $message = sprintf('The association must extend `%s` class, `%s` given.', Association::class, get_class($association));
 93:             throw new InvalidArgumentException($message);
 94:         }
 95: 
 96:         return $this->add($association->getName(), $association);
 97:     }
 98: 
 99:     /**
100:      * Fetch an attached association by name.
101:      *
102:      * @param string $alias The association alias to get.
103:      * @return \Cake\ORM\Association|null Either the association or null.
104:      */
105:     public function get($alias)
106:     {
107:         $alias = strtolower($alias);
108:         if (isset($this->_items[$alias])) {
109:             return $this->_items[$alias];
110:         }
111: 
112:         return null;
113:     }
114: 
115:     /**
116:      * Fetch an association by property name.
117:      *
118:      * @param string $prop The property to find an association by.
119:      * @return \Cake\ORM\Association|null Either the association or null.
120:      */
121:     public function getByProperty($prop)
122:     {
123:         foreach ($this->_items as $assoc) {
124:             if ($assoc->getProperty() === $prop) {
125:                 return $assoc;
126:             }
127:         }
128: 
129:         return null;
130:     }
131: 
132:     /**
133:      * Check for an attached association by name.
134:      *
135:      * @param string $alias The association alias to get.
136:      * @return bool Whether or not the association exists.
137:      */
138:     public function has($alias)
139:     {
140:         return isset($this->_items[strtolower($alias)]);
141:     }
142: 
143:     /**
144:      * Get the names of all the associations in the collection.
145:      *
146:      * @return string[]
147:      */
148:     public function keys()
149:     {
150:         return array_keys($this->_items);
151:     }
152: 
153:     /**
154:      * Get an array of associations matching a specific type.
155:      *
156:      * @param string|array $class The type of associations you want.
157:      *   For example 'BelongsTo' or array like ['BelongsTo', 'HasOne']
158:      * @return array An array of Association objects.
159:      * @deprecated 3.5.3 Use getByType() instead.
160:      */
161:     public function type($class)
162:     {
163:         deprecationWarning(
164:             'AssociationCollection::type() is deprecated. ' .
165:             'Use getByType() instead.'
166:         );
167: 
168:         return $this->getByType($class);
169:     }
170: 
171:     /**
172:      * Get an array of associations matching a specific type.
173:      *
174:      * @param string|array $class The type of associations you want.
175:      *   For example 'BelongsTo' or array like ['BelongsTo', 'HasOne']
176:      * @return array An array of Association objects.
177:      * @since 3.5.3
178:      */
179:     public function getByType($class)
180:     {
181:         $class = array_map('strtolower', (array)$class);
182: 
183:         $out = array_filter($this->_items, function ($assoc) use ($class) {
184:             list(, $name) = namespaceSplit(get_class($assoc));
185: 
186:             return in_array(strtolower($name), $class, true);
187:         });
188: 
189:         return array_values($out);
190:     }
191: 
192:     /**
193:      * Drop/remove an association.
194:      *
195:      * Once removed the association will not longer be reachable
196:      *
197:      * @param string $alias The alias name.
198:      * @return void
199:      */
200:     public function remove($alias)
201:     {
202:         unset($this->_items[strtolower($alias)]);
203:     }
204: 
205:     /**
206:      * Remove all registered associations.
207:      *
208:      * Once removed associations will not longer be reachable
209:      *
210:      * @return void
211:      */
212:     public function removeAll()
213:     {
214:         foreach ($this->_items as $alias => $object) {
215:             $this->remove($alias);
216:         }
217:     }
218: 
219:     /**
220:      * Save all the associations that are parents of the given entity.
221:      *
222:      * Parent associations include any association where the given table
223:      * is the owning side.
224:      *
225:      * @param \Cake\ORM\Table $table The table entity is for.
226:      * @param \Cake\Datasource\EntityInterface $entity The entity to save associated data for.
227:      * @param array $associations The list of associations to save parents from.
228:      *   associations not in this list will not be saved.
229:      * @param array $options The options for the save operation.
230:      * @return bool Success
231:      */
232:     public function saveParents(Table $table, EntityInterface $entity, $associations, array $options = [])
233:     {
234:         if (empty($associations)) {
235:             return true;
236:         }
237: 
238:         return $this->_saveAssociations($table, $entity, $associations, $options, false);
239:     }
240: 
241:     /**
242:      * Save all the associations that are children of the given entity.
243:      *
244:      * Child associations include any association where the given table
245:      * is not the owning side.
246:      *
247:      * @param \Cake\ORM\Table $table The table entity is for.
248:      * @param \Cake\Datasource\EntityInterface $entity The entity to save associated data for.
249:      * @param array $associations The list of associations to save children from.
250:      *   associations not in this list will not be saved.
251:      * @param array $options The options for the save operation.
252:      * @return bool Success
253:      */
254:     public function saveChildren(Table $table, EntityInterface $entity, array $associations, array $options)
255:     {
256:         if (empty($associations)) {
257:             return true;
258:         }
259: 
260:         return $this->_saveAssociations($table, $entity, $associations, $options, true);
261:     }
262: 
263:     /**
264:      * Helper method for saving an association's data.
265:      *
266:      * @param \Cake\ORM\Table $table The table the save is currently operating on
267:      * @param \Cake\Datasource\EntityInterface $entity The entity to save
268:      * @param array $associations Array of associations to save.
269:      * @param array $options Original options
270:      * @param bool $owningSide Compared with association classes'
271:      *   isOwningSide method.
272:      * @return bool Success
273:      * @throws \InvalidArgumentException When an unknown alias is used.
274:      */
275:     protected function _saveAssociations($table, $entity, $associations, $options, $owningSide)
276:     {
277:         unset($options['associated']);
278:         foreach ($associations as $alias => $nested) {
279:             if (is_int($alias)) {
280:                 $alias = $nested;
281:                 $nested = [];
282:             }
283:             $relation = $this->get($alias);
284:             if (!$relation) {
285:                 $msg = sprintf(
286:                     'Cannot save %s, it is not associated to %s',
287:                     $alias,
288:                     $table->getAlias()
289:                 );
290:                 throw new InvalidArgumentException($msg);
291:             }
292:             if ($relation->isOwningSide($table) !== $owningSide) {
293:                 continue;
294:             }
295:             if (!$this->_save($relation, $entity, $nested, $options)) {
296:                 return false;
297:             }
298:         }
299: 
300:         return true;
301:     }
302: 
303:     /**
304:      * Helper method for saving an association's data.
305:      *
306:      * @param \Cake\ORM\Association $association The association object to save with.
307:      * @param \Cake\Datasource\EntityInterface $entity The entity to save
308:      * @param array $nested Options for deeper associations
309:      * @param array $options Original options
310:      * @return bool Success
311:      */
312:     protected function _save($association, $entity, $nested, $options)
313:     {
314:         if (!$entity->isDirty($association->getProperty())) {
315:             return true;
316:         }
317:         if (!empty($nested)) {
318:             $options = (array)$nested + $options;
319:         }
320: 
321:         return (bool)$association->saveAssociated($entity, $options);
322:     }
323: 
324:     /**
325:      * Cascade a delete across the various associations.
326:      * Cascade first across associations for which cascadeCallbacks is true.
327:      *
328:      * @param \Cake\Datasource\EntityInterface $entity The entity to delete associations for.
329:      * @param array $options The options used in the delete operation.
330:      * @return void
331:      */
332:     public function cascadeDelete(EntityInterface $entity, array $options)
333:     {
334:         $noCascade = $this->_getNoCascadeItems($entity, $options);
335:         foreach ($noCascade as $assoc) {
336:             $assoc->cascadeDelete($entity, $options);
337:         }
338:     }
339: 
340:     /**
341:      * Returns items that have no cascade callback.
342:      *
343:      * @param \Cake\Datasource\EntityInterface $entity The entity to delete associations for.
344:      * @param array $options The options used in the delete operation.
345:      * @return \Cake\ORM\Association[]
346:      */
347:     protected function _getNoCascadeItems($entity, $options)
348:     {
349:         $noCascade = [];
350:         foreach ($this->_items as $assoc) {
351:             if (!$assoc->getCascadeCallbacks()) {
352:                 $noCascade[] = $assoc;
353:                 continue;
354:             }
355:             $assoc->cascadeDelete($entity, $options);
356:         }
357: 
358:         return $noCascade;
359:     }
360: 
361:     /**
362:      * Returns an associative array of association names out a mixed
363:      * array. If true is passed, then it returns all association names
364:      * in this collection.
365:      *
366:      * @param bool|array $keys the list of association names to normalize
367:      * @return array
368:      */
369:     public function normalizeKeys($keys)
370:     {
371:         if ($keys === true) {
372:             $keys = $this->keys();
373:         }
374: 
375:         if (empty($keys)) {
376:             return [];
377:         }
378: 
379:         return $this->_normalizeAssociations($keys);
380:     }
381: 
382:     /**
383:      * Allow looping through the associations
384:      *
385:      * @return \ArrayIterator
386:      */
387:     public function getIterator()
388:     {
389:         return new ArrayIterator($this->_items);
390:     }
391: }
392: 
Follow @CakePHP
#IRC
OpenHub
Rackspace
  • Business Solutions
  • Showcase
  • Documentation
  • Book
  • API
  • Videos
  • Logos & Trademarks
  • Community
  • Team
  • Issues (Github)
  • YouTube Channel
  • Get Involved
  • Bakery
  • Featured Resources
  • Newsletter
  • Certification
  • My CakePHP
  • CakeFest
  • Facebook
  • Twitter
  • Help & Support
  • Forum
  • Stack Overflow
  • IRC
  • Slack
  • Paid Support

Generated using CakePHP API Docs