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.8 Red Velvet API

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