CakePHP
  • Documentation
    • Book
    • API
    • Videos
    • Reporting Security Issues
    • Privacy Policy
    • Logos & Trademarks
  • Business Solutions
  • Swag
  • Road Trip
  • Team
  • Community
    • Community
    • Get Involved
    • Issues (GitHub)
    • Bakery
    • Featured Resources
    • Training
    • Meetups
    • My CakePHP
    • CakeFest
    • Newsletter
    • Linkedin
    • YouTube
    • Facebook
    • Twitter
    • Mastodon
    • Help & Support
    • Forum
    • Stack Overflow
    • Slack
    • Paid Support
CakePHP

C CakePHP 2.3 API

  • Overview
  • Tree
  • Deprecated
  • Version:
    • 2.3
      • 4.2
      • 4.1
      • 4.0
      • 3.9
      • 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

Packages

  • Cake
    • Cache
      • Engine
    • Configure
    • Console
      • Command
        • Task
    • Controller
      • Component
        • Acl
        • Auth
    • Core
    • Error
    • Event
    • I18n
    • Log
      • Engine
    • Model
      • Behavior
      • Datasource
        • Database
        • Session
      • Validator
    • Network
      • Email
      • Http
    • Routing
      • Filter
      • Route
    • TestSuite
      • Coverage
      • Fixture
      • Reporter
    • Utility
    • View
      • Helper

Classes

  • AclBehavior
  • ContainableBehavior
  • TranslateBehavior
  • TreeBehavior
  1: <?php
  2: /**
  3:  * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
  4:  * Copyright (c) Cake Software Foundation, Inc. (http://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. (http://cakefoundation.org)
 11:  * @link          http://cakephp.org CakePHP(tm) Project
 12:  * @package       Cake.Model.Behavior
 13:  * @since         CakePHP(tm) v 1.2.0.4525
 14:  * @license       http://www.opensource.org/licenses/mit-license.php MIT License
 15:  */
 16: 
 17: App::uses('ModelBehavior', 'Model');
 18: App::uses('I18n', 'I18n');
 19: App::uses('I18nModel', 'Model');
 20: 
 21: /**
 22:  * Translate behavior
 23:  *
 24:  * @package       Cake.Model.Behavior
 25:  * @link http://book.cakephp.org/2.0/en/core-libraries/behaviors/translate.html
 26:  */
 27: class TranslateBehavior extends ModelBehavior {
 28: 
 29: /**
 30:  * Used for runtime configuration of model
 31:  *
 32:  * @var array
 33:  */
 34:     public $runtime = array();
 35: 
 36: /**
 37:  * Stores the joinTable object for generating joins.
 38:  *
 39:  * @var object
 40:  */
 41:     protected $_joinTable;
 42: 
 43: /**
 44:  * Stores the runtime model for generating joins.
 45:  *
 46:  * @var Model
 47:  */
 48:     protected $_runtimeModel;
 49: 
 50: /**
 51:  * Callback
 52:  *
 53:  * $config for TranslateBehavior should be
 54:  * array('fields' => array('field_one',
 55:  * 'field_two' => 'FieldAssoc', 'field_three'))
 56:  *
 57:  * With above example only one permanent hasMany will be joined (for field_two
 58:  * as FieldAssoc)
 59:  *
 60:  * $config could be empty - and translations configured dynamically by
 61:  * bindTranslation() method
 62:  *
 63:  * @param Model $Model Model the behavior is being attached to.
 64:  * @param array $config Array of configuration information.
 65:  * @return mixed
 66:  */
 67:     public function setup(Model $Model, $config = array()) {
 68:         $db = ConnectionManager::getDataSource($Model->useDbConfig);
 69:         if (!$db->connected) {
 70:             trigger_error(
 71:                 __d('cake_dev', 'Datasource %s for TranslateBehavior of model %s is not connected', $Model->useDbConfig, $Model->alias),
 72:                 E_USER_ERROR
 73:             );
 74:             return false;
 75:         }
 76: 
 77:         $this->settings[$Model->alias] = array();
 78:         $this->runtime[$Model->alias] = array('fields' => array());
 79:         $this->translateModel($Model);
 80:         return $this->bindTranslation($Model, $config, false);
 81:     }
 82: 
 83: /**
 84:  * Cleanup Callback unbinds bound translations and deletes setting information.
 85:  *
 86:  * @param Model $Model Model being detached.
 87:  * @return void
 88:  */
 89:     public function cleanup(Model $Model) {
 90:         $this->unbindTranslation($Model);
 91:         unset($this->settings[$Model->alias]);
 92:         unset($this->runtime[$Model->alias]);
 93:     }
 94: 
 95: /**
 96:  * beforeFind Callback
 97:  *
 98:  * @param Model $Model Model find is being run on.
 99:  * @param array $query Array of Query parameters.
100:  * @return array Modified query
101:  */
102:     public function beforeFind(Model $Model, $query) {
103:         $this->runtime[$Model->alias]['virtualFields'] = $Model->virtualFields;
104:         $locale = $this->_getLocale($Model);
105:         if (empty($locale)) {
106:             return $query;
107:         }
108:         $db = $Model->getDataSource();
109:         $RuntimeModel = $this->translateModel($Model);
110: 
111:         if (!empty($RuntimeModel->tablePrefix)) {
112:             $tablePrefix = $RuntimeModel->tablePrefix;
113:         } else {
114:             $tablePrefix = $db->config['prefix'];
115:         }
116:         $joinTable = new StdClass();
117:         $joinTable->tablePrefix = $tablePrefix;
118:         $joinTable->table = $RuntimeModel->table;
119:         $joinTable->schemaName = $RuntimeModel->getDataSource()->getSchemaName();
120: 
121:         $this->_joinTable = $joinTable;
122:         $this->_runtimeModel = $RuntimeModel;
123: 
124:         if (is_string($query['fields']) && "COUNT(*) AS {$db->name('count')}" == $query['fields']) {
125:             $query['fields'] = "COUNT(DISTINCT({$db->name($Model->escapeField())})) {$db->alias}count";
126:             $query['joins'][] = array(
127:                 'type' => 'INNER',
128:                 'alias' => $RuntimeModel->alias,
129:                 'table' => $joinTable,
130:                 'conditions' => array(
131:                     $Model->escapeField() => $db->identifier($RuntimeModel->escapeField('foreign_key')),
132:                     $RuntimeModel->escapeField('model') => $Model->name,
133:                     $RuntimeModel->escapeField('locale') => $locale
134:                 )
135:             );
136:             $conditionFields = $this->_checkConditions($Model, $query);
137:             foreach ($conditionFields as $field) {
138:                 $query = $this->_addJoin($Model, $query, $field, $field, $locale);
139:             }
140:             unset($this->_joinTable, $this->_runtimeModel);
141:             return $query;
142:         }
143: 
144:         $fields = array_merge(
145:             $this->settings[$Model->alias],
146:             $this->runtime[$Model->alias]['fields']
147:         );
148:         $addFields = array();
149:         if (empty($query['fields'])) {
150:             $addFields = $fields;
151:         } elseif (is_array($query['fields'])) {
152:             $isAllFields = (
153:                 in_array($Model->alias . '.' . '*', $query['fields']) ||
154:                 in_array($Model->escapeField('*'), $query['fields'])
155:             );
156:             foreach ($fields as $key => $value) {
157:                 $field = (is_numeric($key)) ? $value : $key;
158:                 if (
159:                     $isAllFields ||
160:                     in_array($Model->alias . '.' . $field, $query['fields']) ||
161:                     in_array($field, $query['fields'])
162:                 ) {
163:                     $addFields[] = $field;
164:                 }
165:             }
166:         }
167: 
168:         $this->runtime[$Model->alias]['virtualFields'] = $Model->virtualFields;
169:         if ($addFields) {
170:             foreach ($addFields as $_f => $field) {
171:                 $aliasField = is_numeric($_f) ? $field : $_f;
172: 
173:                 foreach (array($aliasField, $Model->alias . '.' . $aliasField) as $_field) {
174:                     $key = array_search($_field, (array)$query['fields']);
175: 
176:                     if ($key !== false) {
177:                         unset($query['fields'][$key]);
178:                     }
179:                 }
180:                 $query = $this->_addJoin($Model, $query, $field, $aliasField, $locale);
181:             }
182:         }
183:         $this->runtime[$Model->alias]['beforeFind'] = $addFields;
184:         unset($this->_joinTable, $this->_runtimeModel);
185:         return $query;
186:     }
187: 
188: /**
189:  * Check a query's conditions for translated fields.
190:  * Return an array of translated fields found in the conditions.
191:  *
192:  * @param Model $Model The model being read.
193:  * @param array $query The query array.
194:  * @return array The list of translated fields that are in the conditions.
195:  */
196:     protected function _checkConditions(Model $Model, $query) {
197:         $conditionFields = array();
198:         if (empty($query['conditions']) || (!empty($query['conditions']) && !is_array($query['conditions']))) {
199:             return $conditionFields;
200:         }
201:         foreach ($query['conditions'] as $col => $val) {
202:             foreach ($this->settings[$Model->alias] as $field => $assoc) {
203:                 if (is_numeric($field)) {
204:                     $field = $assoc;
205:                 }
206:                 if (strpos($col, $field) !== false) {
207:                     $conditionFields[] = $field;
208:                 }
209:             }
210:         }
211:         return $conditionFields;
212:     }
213: 
214: /**
215:  * Appends a join for translated fields.
216:  *
217:  * @param Model $Model The model being worked on.
218:  * @param array $query The query array to append a join to.
219:  * @param string $field The field name being joined.
220:  * @param string $aliasField The aliased field name being joined.
221:  * @param string|array $locale The locale(s) having joins added.
222:  * @return array The modified query
223:  */
224:     protected function _addJoin(Model $Model, $query, $field, $aliasField, $locale) {
225:         $db = ConnectionManager::getDataSource($Model->useDbConfig);
226:         $RuntimeModel = $this->_runtimeModel;
227:         $joinTable = $this->_joinTable;
228:         $aliasVirtual = "i18n_{$field}";
229:         $alias = "I18n__{$field}";
230:         if (is_array($locale)) {
231:             foreach ($locale as $_locale) {
232:                 $aliasVirtualLocale = "{$aliasVirtual}_{$_locale}";
233:                 $aliasLocale = "{$alias}__{$_locale}";
234:                 $Model->virtualFields[$aliasVirtualLocale] = "{$aliasLocale}.content";
235:                 if (!empty($query['fields']) && is_array($query['fields'])) {
236:                     $query['fields'][] = $aliasVirtualLocale;
237:                 }
238:                 $query['joins'][] = array(
239:                     'type' => 'LEFT',
240:                     'alias' => $aliasLocale,
241:                     'table' => $joinTable,
242:                     'conditions' => array(
243:                         $Model->escapeField() => $db->identifier("{$aliasLocale}.foreign_key"),
244:                         "{$aliasLocale}.model" => $Model->name,
245:                         "{$aliasLocale}.{$RuntimeModel->displayField}" => $aliasField,
246:                         "{$aliasLocale}.locale" => $_locale
247:                     )
248:                 );
249:             }
250:         } else {
251:             $Model->virtualFields[$aliasVirtual] = "{$alias}.content";
252:             if (!empty($query['fields']) && is_array($query['fields'])) {
253:                 $query['fields'][] = $aliasVirtual;
254:             }
255:             $query['joins'][] = array(
256:                 'type' => 'INNER',
257:                 'alias' => $alias,
258:                 'table' => $joinTable,
259:                 'conditions' => array(
260:                     "{$Model->alias}.{$Model->primaryKey}" => $db->identifier("{$alias}.foreign_key"),
261:                     "{$alias}.model" => $Model->name,
262:                     "{$alias}.{$RuntimeModel->displayField}" => $aliasField,
263:                     "{$alias}.locale" => $locale
264:                 )
265:             );
266:         }
267:         return $query;
268:     }
269: 
270: /**
271:  * afterFind Callback
272:  *
273:  * @param Model $Model Model find was run on
274:  * @param array $results Array of model results.
275:  * @param boolean $primary Did the find originate on $model.
276:  * @return array Modified results
277:  */
278:     public function afterFind(Model $Model, $results, $primary) {
279:         $Model->virtualFields = $this->runtime[$Model->alias]['virtualFields'];
280:         $this->runtime[$Model->alias]['virtualFields'] = $this->runtime[$Model->alias]['fields'] = array();
281:         $locale = $this->_getLocale($Model);
282: 
283:         if (empty($locale) || empty($results) || empty($this->runtime[$Model->alias]['beforeFind'])) {
284:             return $results;
285:         }
286:         $beforeFind = $this->runtime[$Model->alias]['beforeFind'];
287: 
288:         foreach ($results as $key => &$row) {
289:             $results[$key][$Model->alias]['locale'] = (is_array($locale)) ? current($locale) : $locale;
290:             foreach ($beforeFind as $_f => $field) {
291:                 $aliasField = is_numeric($_f) ? $field : $_f;
292:                 $aliasVirtual = "i18n_{$field}";
293:                 if (is_array($locale)) {
294:                     foreach ($locale as $_locale) {
295:                         $aliasVirtualLocale = "{$aliasVirtual}_{$_locale}";
296:                         if (!isset($row[$Model->alias][$aliasField]) && !empty($row[$Model->alias][$aliasVirtualLocale])) {
297:                             $row[$Model->alias][$aliasField] = $row[$Model->alias][$aliasVirtualLocale];
298:                             $row[$Model->alias]['locale'] = $_locale;
299:                         }
300:                         unset($row[$Model->alias][$aliasVirtualLocale]);
301:                     }
302: 
303:                     if (!isset($row[$Model->alias][$aliasField])) {
304:                         $row[$Model->alias][$aliasField] = '';
305:                     }
306:                 } else {
307:                     $value = '';
308:                     if (!empty($row[$Model->alias][$aliasVirtual])) {
309:                         $value = $row[$Model->alias][$aliasVirtual];
310:                     }
311:                     $row[$Model->alias][$aliasField] = $value;
312:                     unset($row[$Model->alias][$aliasVirtual]);
313:                 }
314:             }
315:         }
316:         return $results;
317:     }
318: 
319: /**
320:  * beforeValidate Callback
321:  *
322:  * @param Model $Model Model invalidFields was called on.
323:  * @return boolean
324:  */
325:     public function beforeValidate(Model $Model) {
326:         unset($this->runtime[$Model->alias]['beforeSave']);
327:         $this->_setRuntimeData($Model);
328:         return true;
329:     }
330: 
331: /**
332:  * beforeSave callback.
333:  *
334:  * Copies data into the runtime property when `$options['validate']` is
335:  * disabled. Or the runtime data hasn't been set yet.
336:  *
337:  * @param Model $Model Model save was called on.
338:  * @return boolean true.
339:  */
340:     public function beforeSave(Model $Model, $options = array()) {
341:         if (isset($options['validate']) && !$options['validate']) {
342:             unset($this->runtime[$Model->alias]['beforeSave']);
343:         }
344:         if (isset($this->runtime[$Model->alias]['beforeSave'])) {
345:             return true;
346:         }
347:         $this->_setRuntimeData($Model);
348:         return true;
349:     }
350: 
351: /**
352:  * Sets the runtime data.
353:  *
354:  * Used from beforeValidate() and beforeSave() for compatibility issues,
355:  * and to allow translations to be persisted even when validation
356:  * is disabled.
357:  *
358:  * @param Model $Model
359:  * @return void
360:  */
361:     protected function _setRuntimeData(Model $Model) {
362:         $locale = $this->_getLocale($Model);
363:         if (empty($locale)) {
364:             return true;
365:         }
366:         $fields = array_merge($this->settings[$Model->alias], $this->runtime[$Model->alias]['fields']);
367:         $tempData = array();
368: 
369:         foreach ($fields as $key => $value) {
370:             $field = (is_numeric($key)) ? $value : $key;
371: 
372:             if (isset($Model->data[$Model->alias][$field])) {
373:                 $tempData[$field] = $Model->data[$Model->alias][$field];
374:                 if (is_array($Model->data[$Model->alias][$field])) {
375:                     if (is_string($locale) && !empty($Model->data[$Model->alias][$field][$locale])) {
376:                         $Model->data[$Model->alias][$field] = $Model->data[$Model->alias][$field][$locale];
377:                     } else {
378:                         $values = array_values($Model->data[$Model->alias][$field]);
379:                         $Model->data[$Model->alias][$field] = $values[0];
380:                     }
381:                 }
382:             }
383:         }
384:         $this->runtime[$Model->alias]['beforeSave'] = $tempData;
385:     }
386: 
387: /**
388:  * Restores model data to the original data.
389:  * This solves issues with saveAssociated and validate = first.
390:  *
391:  * @param Model $model
392:  * @return void
393:  */
394:     public function afterValidate(Model $Model) {
395:         $Model->data[$Model->alias] = array_merge(
396:             $Model->data[$Model->alias],
397:             $this->runtime[$Model->alias]['beforeSave']
398:         );
399:         return true;
400:     }
401: 
402: /**
403:  * afterSave Callback
404:  *
405:  * @param Model $Model Model the callback is called on
406:  * @param boolean $created Whether or not the save created a record.
407:  * @return void
408:  */
409:     public function afterSave(Model $Model, $created) {
410:         if (!isset($this->runtime[$Model->alias]['beforeValidate']) && !isset($this->runtime[$Model->alias]['beforeSave'])) {
411:             return true;
412:         }
413:         if (isset($this->runtime[$Model->alias]['beforeValidate'])) {
414:             $tempData = $this->runtime[$Model->alias]['beforeValidate'];
415:         } else {
416:             $tempData = $this->runtime[$Model->alias]['beforeSave'];
417:         }
418: 
419:         unset($this->runtime[$Model->alias]['beforeValidate'], $this->runtime[$Model->alias]['beforeSave']);
420:         $conditions = array('model' => $Model->name, 'foreign_key' => $Model->id);
421:         $RuntimeModel = $this->translateModel($Model);
422: 
423:         if ($created) {
424:             $tempData = $this->_prepareTranslations($Model, $tempData);
425:         }
426:         $locale = $this->_getLocale($Model);
427: 
428:         foreach ($tempData as $field => $value) {
429:             unset($conditions['content']);
430:             $conditions['field'] = $field;
431:             if (is_array($value)) {
432:                 $conditions['locale'] = array_keys($value);
433:             } else {
434:                 $conditions['locale'] = $locale;
435:                 if (is_array($locale)) {
436:                     $value = array($locale[0] => $value);
437:                 } else {
438:                     $value = array($locale => $value);
439:                 }
440:             }
441:             $translations = $RuntimeModel->find('list', array(
442:                 'conditions' => $conditions,
443:                 'fields' => array(
444:                     $RuntimeModel->alias . '.locale',
445:                     $RuntimeModel->alias . '.id'
446:                 )
447:             ));
448:             foreach ($value as $_locale => $_value) {
449:                 $RuntimeModel->create();
450:                 $conditions['locale'] = $_locale;
451:                 $conditions['content'] = $_value;
452:                 if (array_key_exists($_locale, $translations)) {
453:                     $RuntimeModel->save(array(
454:                         $RuntimeModel->alias => array_merge(
455:                             $conditions, array('id' => $translations[$_locale])
456:                         )
457:                     ));
458:                 } else {
459:                     $RuntimeModel->save(array($RuntimeModel->alias => $conditions));
460:                 }
461:             }
462:         }
463:     }
464: 
465: /**
466:  * Prepares the data to be saved for translated records.
467:  * Add blank fields, and populates data for multi-locale saves.
468:  *
469:  * @param Model $Model Model instance
470:  * @param array $data The sparse data that was provided.
471:  * @return array The fully populated data to save.
472:  */
473:     protected function _prepareTranslations(Model $Model, $data) {
474:         $fields = array_merge($this->settings[$Model->alias], $this->runtime[$Model->alias]['fields']);
475:         $locales = array();
476:         foreach ($data as $key => $value) {
477:             if (is_array($value)) {
478:                 $locales = array_merge($locales, array_keys($value));
479:             }
480:         }
481:         $locales = array_unique($locales);
482:         $hasLocales = count($locales) > 0;
483: 
484:         foreach ($fields as $key => $field) {
485:             if (!is_numeric($key)) {
486:                 $field = $key;
487:             }
488:             if ($hasLocales && !isset($data[$field])) {
489:                 $data[$field] = array_fill_keys($locales, '');
490:             } elseif (!isset($data[$field])) {
491:                 $data[$field] = '';
492:             }
493:         }
494:         return $data;
495:     }
496: 
497: /**
498:  * afterDelete Callback
499:  *
500:  * @param Model $Model Model the callback was run on.
501:  * @return void
502:  */
503:     public function afterDelete(Model $Model) {
504:         $RuntimeModel = $this->translateModel($Model);
505:         $conditions = array('model' => $Model->name, 'foreign_key' => $Model->id);
506:         $RuntimeModel->deleteAll($conditions);
507:     }
508: 
509: /**
510:  * Get selected locale for model
511:  *
512:  * @param Model $Model Model the locale needs to be set/get on.
513:  * @return mixed string or false
514:  */
515:     protected function _getLocale(Model $Model) {
516:         if (!isset($Model->locale) || $Model->locale === null) {
517:             $I18n = I18n::getInstance();
518:             $I18n->l10n->get(Configure::read('Config.language'));
519:             $Model->locale = $I18n->l10n->locale;
520:         }
521: 
522:         return $Model->locale;
523:     }
524: 
525: /**
526:  * Get instance of model for translations.
527:  *
528:  * If the model has a translateModel property set, this will be used as the class
529:  * name to find/use. If no translateModel property is found 'I18nModel' will be used.
530:  *
531:  * @param Model $Model Model to get a translatemodel for.
532:  * @return Model
533:  */
534:     public function translateModel(Model $Model) {
535:         if (!isset($this->runtime[$Model->alias]['model'])) {
536:             if (!isset($Model->translateModel) || empty($Model->translateModel)) {
537:                 $className = 'I18nModel';
538:             } else {
539:                 $className = $Model->translateModel;
540:             }
541: 
542:             $this->runtime[$Model->alias]['model'] = ClassRegistry::init($className);
543:         }
544:         if (!empty($Model->translateTable) && $Model->translateTable !== $this->runtime[$Model->alias]['model']->useTable) {
545:             $this->runtime[$Model->alias]['model']->setSource($Model->translateTable);
546:         } elseif (empty($Model->translateTable) && empty($Model->translateModel)) {
547:             $this->runtime[$Model->alias]['model']->setSource('i18n');
548:         }
549:         return $this->runtime[$Model->alias]['model'];
550:     }
551: 
552: /**
553:  * Bind translation for fields, optionally with hasMany association for
554:  * fake field.
555:  *
556:  * *Note* You should avoid binding translations that overlap existing model properties.
557:  * This can cause un-expected and un-desirable behavior.
558:  *
559:  * @param Model $Model instance of model
560:  * @param string|array $fields string with field or array(field1, field2=>AssocName, field3)
561:  * @param boolean $reset Leave true to have the fields only modified for the next operation.
562:  *   if false the field will be added for all future queries.
563:  * @return boolean
564:  * @throws CakeException when attempting to bind a translating called name. This is not allowed
565:  *   as it shadows Model::$name.
566:  */
567:     public function bindTranslation(Model $Model, $fields, $reset = true) {
568:         if (is_string($fields)) {
569:             $fields = array($fields);
570:         }
571:         $associations = array();
572:         $RuntimeModel = $this->translateModel($Model);
573:         $default = array('className' => $RuntimeModel->alias, 'foreignKey' => 'foreign_key');
574: 
575:         foreach ($fields as $key => $value) {
576:             if (is_numeric($key)) {
577:                 $field = $value;
578:                 $association = null;
579:             } else {
580:                 $field = $key;
581:                 $association = $value;
582:             }
583:             if ($association === 'name') {
584:                 throw new CakeException(
585:                     __d('cake_dev', 'You cannot bind a translation named "name".')
586:                 );
587:             }
588: 
589:             $this->_removeField($Model, $field);
590: 
591:             if ($association === null) {
592:                 if ($reset) {
593:                     $this->runtime[$Model->alias]['fields'][] = $field;
594:                 } else {
595:                     $this->settings[$Model->alias][] = $field;
596:                 }
597:             } else {
598:                 if ($reset) {
599:                     $this->runtime[$Model->alias]['fields'][$field] = $association;
600:                 } else {
601:                     $this->settings[$Model->alias][$field] = $association;
602:                 }
603: 
604:                 foreach (array('hasOne', 'hasMany', 'belongsTo', 'hasAndBelongsToMany') as $type) {
605:                     if (isset($Model->{$type}[$association]) || isset($Model->__backAssociation[$type][$association])) {
606:                         trigger_error(
607:                             __d('cake_dev', 'Association %s is already bound to model %s', $association, $Model->alias),
608:                             E_USER_ERROR
609:                         );
610:                         return false;
611:                     }
612:                 }
613:                 $associations[$association] = array_merge($default, array('conditions' => array(
614:                     'model' => $Model->name,
615:                     $RuntimeModel->displayField => $field
616:                 )));
617:             }
618:         }
619: 
620:         if (!empty($associations)) {
621:             $Model->bindModel(array('hasMany' => $associations), $reset);
622:         }
623:         return true;
624:     }
625: 
626: /**
627:  * Update runtime setting for a given field.
628:  *
629:  * @param Model $Model Model instance
630:  * @param string $field The field to update.
631:  * @return void
632:  */
633:     protected function _removeField(Model $Model, $field) {
634:         if (array_key_exists($field, $this->settings[$Model->alias])) {
635:             unset($this->settings[$Model->alias][$field]);
636:         } elseif (in_array($field, $this->settings[$Model->alias])) {
637:             $this->settings[$Model->alias] = array_merge(array_diff($this->settings[$Model->alias], array($field)));
638:         }
639: 
640:         if (array_key_exists($field, $this->runtime[$Model->alias]['fields'])) {
641:             unset($this->runtime[$Model->alias]['fields'][$field]);
642:         } elseif (in_array($field, $this->runtime[$Model->alias]['fields'])) {
643:             $this->runtime[$Model->alias]['fields'] = array_merge(array_diff($this->runtime[$Model->alias]['fields'], array($field)));
644:         }
645:     }
646: 
647: /**
648:  * Unbind translation for fields, optionally unbinds hasMany association for
649:  * fake field
650:  *
651:  * @param Model $Model instance of model
652:  * @param string|array $fields string with field, or array(field1, field2=>AssocName, field3), or null for
653:  *    unbind all original translations
654:  * @return boolean
655:  */
656:     public function unbindTranslation(Model $Model, $fields = null) {
657:         if (empty($fields) && empty($this->settings[$Model->alias])) {
658:             return false;
659:         }
660:         if (empty($fields)) {
661:             return $this->unbindTranslation($Model, $this->settings[$Model->alias]);
662:         }
663: 
664:         if (is_string($fields)) {
665:             $fields = array($fields);
666:         }
667:         $associations = array();
668: 
669:         foreach ($fields as $key => $value) {
670:             if (is_numeric($key)) {
671:                 $field = $value;
672:                 $association = null;
673:             } else {
674:                 $field = $key;
675:                 $association = $value;
676:             }
677: 
678:             $this->_removeField($Model, $field);
679: 
680:             if ($association !== null && (isset($Model->hasMany[$association]) || isset($Model->__backAssociation['hasMany'][$association]))) {
681:                 $associations[] = $association;
682:             }
683:         }
684: 
685:         if (!empty($associations)) {
686:             $Model->unbindModel(array('hasMany' => $associations), false);
687:         }
688:         return true;
689:     }
690: 
691: }
692: 
OpenHub
Rackspace
Rackspace
  • Business Solutions
  • Showcase
  • Documentation
  • Book
  • API
  • Videos
  • Reporting Security Issues
  • Privacy Policy
  • Logos & Trademarks
  • Community
  • Get Involved
  • Issues (GitHub)
  • Bakery
  • Featured Resources
  • Training
  • Meetups
  • My CakePHP
  • CakeFest
  • Newsletter
  • Linkedin
  • YouTube
  • Facebook
  • Twitter
  • Mastodon
  • Help & Support
  • Forum
  • Stack Overflow
  • Slack
  • Paid Support

Generated using CakePHP API Docs