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.4 API

  • Overview
  • Tree
  • Deprecated
  • Version:
    • 2.4
      • 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']) && $query['fields'] === "COUNT(*) AS {$db->name('count')}") {
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:         } elseif (is_string($query['fields'])) {
143:             $query['fields'] = String::tokenize($query['fields']);
144:         }
145: 
146:         $fields = array_merge(
147:             $this->settings[$Model->alias],
148:             $this->runtime[$Model->alias]['fields']
149:         );
150:         $addFields = array();
151:         if (empty($query['fields'])) {
152:             $addFields = $fields;
153:         } elseif (is_array($query['fields'])) {
154:             $isAllFields = (
155:                 in_array($Model->alias . '.' . '*', $query['fields']) ||
156:                 in_array($Model->escapeField('*'), $query['fields'])
157:             );
158:             foreach ($fields as $key => $value) {
159:                 $field = (is_numeric($key)) ? $value : $key;
160:                 if (
161:                     $isAllFields ||
162:                     in_array($Model->alias . '.' . $field, $query['fields']) ||
163:                     in_array($field, $query['fields'])
164:                 ) {
165:                     $addFields[] = $field;
166:                 }
167:             }
168:         }
169: 
170:         $this->runtime[$Model->alias]['virtualFields'] = $Model->virtualFields;
171:         if ($addFields) {
172:             foreach ($addFields as $_f => $field) {
173:                 $aliasField = is_numeric($_f) ? $field : $_f;
174: 
175:                 foreach (array($aliasField, $Model->alias . '.' . $aliasField) as $_field) {
176:                     $key = array_search($_field, (array)$query['fields']);
177: 
178:                     if ($key !== false) {
179:                         unset($query['fields'][$key]);
180:                     }
181:                 }
182:                 $query = $this->_addJoin($Model, $query, $field, $aliasField, $locale);
183:             }
184:         }
185:         $this->runtime[$Model->alias]['beforeFind'] = $addFields;
186:         unset($this->_joinTable, $this->_runtimeModel);
187:         return $query;
188:     }
189: 
190: /**
191:  * Check a query's conditions for translated fields.
192:  * Return an array of translated fields found in the conditions.
193:  *
194:  * @param Model $Model The model being read.
195:  * @param array $query The query array.
196:  * @return array The list of translated fields that are in the conditions.
197:  */
198:     protected function _checkConditions(Model $Model, $query) {
199:         $conditionFields = array();
200:         if (empty($query['conditions']) || (!empty($query['conditions']) && !is_array($query['conditions']))) {
201:             return $conditionFields;
202:         }
203:         foreach ($query['conditions'] as $col => $val) {
204:             foreach ($this->settings[$Model->alias] as $field => $assoc) {
205:                 if (is_numeric($field)) {
206:                     $field = $assoc;
207:                 }
208:                 if (strpos($col, $field) !== false) {
209:                     $conditionFields[] = $field;
210:                 }
211:             }
212:         }
213:         return $conditionFields;
214:     }
215: 
216: /**
217:  * Appends a join for translated fields.
218:  *
219:  * @param Model $Model The model being worked on.
220:  * @param array $query The query array to append a join to.
221:  * @param string $field The field name being joined.
222:  * @param string $aliasField The aliased field name being joined.
223:  * @param string|array $locale The locale(s) having joins added.
224:  * @return array The modified query
225:  */
226:     protected function _addJoin(Model $Model, $query, $field, $aliasField, $locale) {
227:         $db = ConnectionManager::getDataSource($Model->useDbConfig);
228:         $RuntimeModel = $this->_runtimeModel;
229:         $joinTable = $this->_joinTable;
230:         $aliasVirtual = "i18n_{$field}";
231:         $alias = "I18n__{$field}";
232:         if (is_array($locale)) {
233:             foreach ($locale as $_locale) {
234:                 $aliasVirtualLocale = "{$aliasVirtual}_{$_locale}";
235:                 $aliasLocale = "{$alias}__{$_locale}";
236:                 $Model->virtualFields[$aliasVirtualLocale] = "{$aliasLocale}.content";
237:                 if (!empty($query['fields']) && is_array($query['fields'])) {
238:                     $query['fields'][] = $aliasVirtualLocale;
239:                 }
240:                 $query['joins'][] = array(
241:                     'type' => 'LEFT',
242:                     'alias' => $aliasLocale,
243:                     'table' => $joinTable,
244:                     'conditions' => array(
245:                         $Model->escapeField() => $db->identifier("{$aliasLocale}.foreign_key"),
246:                         "{$aliasLocale}.model" => $Model->name,
247:                         "{$aliasLocale}.{$RuntimeModel->displayField}" => $aliasField,
248:                         "{$aliasLocale}.locale" => $_locale
249:                     )
250:                 );
251:             }
252:         } else {
253:             $Model->virtualFields[$aliasVirtual] = "{$alias}.content";
254:             if (!empty($query['fields']) && is_array($query['fields'])) {
255:                 $query['fields'][] = $aliasVirtual;
256:             }
257:             $query['joins'][] = array(
258:                 'type' => 'INNER',
259:                 'alias' => $alias,
260:                 'table' => $joinTable,
261:                 'conditions' => array(
262:                     "{$Model->alias}.{$Model->primaryKey}" => $db->identifier("{$alias}.foreign_key"),
263:                     "{$alias}.model" => $Model->name,
264:                     "{$alias}.{$RuntimeModel->displayField}" => $aliasField,
265:                     "{$alias}.locale" => $locale
266:                 )
267:             );
268:         }
269:         return $query;
270:     }
271: 
272: /**
273:  * afterFind Callback
274:  *
275:  * @param Model $Model Model find was run on
276:  * @param array $results Array of model results.
277:  * @param boolean $primary Did the find originate on $model.
278:  * @return array Modified results
279:  */
280:     public function afterFind(Model $Model, $results, $primary = false) {
281:         $Model->virtualFields = $this->runtime[$Model->alias]['virtualFields'];
282: 
283:         $this->runtime[$Model->alias]['virtualFields'] = $this->runtime[$Model->alias]['fields'] = array();
284:         if (!empty($this->runtime[$Model->alias]['restoreFields'])) {
285:             $this->runtime[$Model->alias]['fields'] = $this->runtime[$Model->alias]['restoreFields'];
286:             unset($this->runtime[$Model->alias]['restoreFields']);
287:         }
288: 
289:         $locale = $this->_getLocale($Model);
290: 
291:         if (empty($locale) || empty($results) || empty($this->runtime[$Model->alias]['beforeFind'])) {
292:             return $results;
293:         }
294:         $beforeFind = $this->runtime[$Model->alias]['beforeFind'];
295: 
296:         foreach ($results as $key => &$row) {
297:             $results[$key][$Model->alias]['locale'] = (is_array($locale)) ? current($locale) : $locale;
298:             foreach ($beforeFind as $_f => $field) {
299:                 $aliasField = is_numeric($_f) ? $field : $_f;
300:                 $aliasVirtual = "i18n_{$field}";
301:                 if (is_array($locale)) {
302:                     foreach ($locale as $_locale) {
303:                         $aliasVirtualLocale = "{$aliasVirtual}_{$_locale}";
304:                         if (!isset($row[$Model->alias][$aliasField]) && !empty($row[$Model->alias][$aliasVirtualLocale])) {
305:                             $row[$Model->alias][$aliasField] = $row[$Model->alias][$aliasVirtualLocale];
306:                             $row[$Model->alias]['locale'] = $_locale;
307:                         }
308:                         unset($row[$Model->alias][$aliasVirtualLocale]);
309:                     }
310: 
311:                     if (!isset($row[$Model->alias][$aliasField])) {
312:                         $row[$Model->alias][$aliasField] = '';
313:                     }
314:                 } else {
315:                     $value = '';
316:                     if (isset($row[$Model->alias][$aliasVirtual])) {
317:                         $value = $row[$Model->alias][$aliasVirtual];
318:                     }
319:                     $row[$Model->alias][$aliasField] = $value;
320:                     unset($row[$Model->alias][$aliasVirtual]);
321:                 }
322:             }
323:         }
324:         return $results;
325:     }
326: 
327: /**
328:  * beforeValidate Callback
329:  *
330:  * @param Model $Model Model invalidFields was called on.
331:  * @param array $options Options passed from Model::save().
332:  * @return boolean
333:  * @see Model::save()
334:  */
335:     public function beforeValidate(Model $Model, $options = array()) {
336:         unset($this->runtime[$Model->alias]['beforeSave']);
337:         $this->_setRuntimeData($Model);
338:         return true;
339:     }
340: 
341: /**
342:  * beforeSave callback.
343:  *
344:  * Copies data into the runtime property when `$options['validate']` is
345:  * disabled. Or the runtime data hasn't been set yet.
346:  *
347:  * @param Model $Model Model save was called on.
348:  * @param array $options Options passed from Model::save().
349:  * @return boolean true.
350:  * @see Model::save()
351:  */
352:     public function beforeSave(Model $Model, $options = array()) {
353:         if (isset($options['validate']) && !$options['validate']) {
354:             unset($this->runtime[$Model->alias]['beforeSave']);
355:         }
356:         if (isset($this->runtime[$Model->alias]['beforeSave'])) {
357:             return true;
358:         }
359:         $this->_setRuntimeData($Model);
360:         return true;
361:     }
362: 
363: /**
364:  * Sets the runtime data.
365:  *
366:  * Used from beforeValidate() and beforeSave() for compatibility issues,
367:  * and to allow translations to be persisted even when validation
368:  * is disabled.
369:  *
370:  * @param Model $Model
371:  * @return void
372:  */
373:     protected function _setRuntimeData(Model $Model) {
374:         $locale = $this->_getLocale($Model);
375:         if (empty($locale)) {
376:             return true;
377:         }
378:         $fields = array_merge($this->settings[$Model->alias], $this->runtime[$Model->alias]['fields']);
379:         $tempData = array();
380: 
381:         foreach ($fields as $key => $value) {
382:             $field = (is_numeric($key)) ? $value : $key;
383: 
384:             if (isset($Model->data[$Model->alias][$field])) {
385:                 $tempData[$field] = $Model->data[$Model->alias][$field];
386:                 if (is_array($Model->data[$Model->alias][$field])) {
387:                     if (is_string($locale) && !empty($Model->data[$Model->alias][$field][$locale])) {
388:                         $Model->data[$Model->alias][$field] = $Model->data[$Model->alias][$field][$locale];
389:                     } else {
390:                         $values = array_values($Model->data[$Model->alias][$field]);
391:                         $Model->data[$Model->alias][$field] = $values[0];
392:                     }
393:                 }
394:             }
395:         }
396:         $this->runtime[$Model->alias]['beforeSave'] = $tempData;
397:     }
398: 
399: /**
400:  * Restores model data to the original data.
401:  * This solves issues with saveAssociated and validate = first.
402:  *
403:  * @param Model $model
404:  * @return void
405:  */
406:     public function afterValidate(Model $Model) {
407:         $Model->data[$Model->alias] = array_merge(
408:             $Model->data[$Model->alias],
409:             $this->runtime[$Model->alias]['beforeSave']
410:         );
411:         return true;
412:     }
413: 
414: /**
415:  * afterSave Callback
416:  *
417:  * @param Model $Model Model the callback is called on
418:  * @param boolean $created Whether or not the save created a record.
419:  * @param array $options Options passed from Model::save().
420:  * @return void
421:  */
422:     public function afterSave(Model $Model, $created, $options = array()) {
423:         if (!isset($this->runtime[$Model->alias]['beforeValidate']) && !isset($this->runtime[$Model->alias]['beforeSave'])) {
424:             return true;
425:         }
426:         if (isset($this->runtime[$Model->alias]['beforeValidate'])) {
427:             $tempData = $this->runtime[$Model->alias]['beforeValidate'];
428:         } else {
429:             $tempData = $this->runtime[$Model->alias]['beforeSave'];
430:         }
431: 
432:         unset($this->runtime[$Model->alias]['beforeValidate'], $this->runtime[$Model->alias]['beforeSave']);
433:         $conditions = array('model' => $Model->name, 'foreign_key' => $Model->id);
434:         $RuntimeModel = $this->translateModel($Model);
435: 
436:         if ($created) {
437:             $tempData = $this->_prepareTranslations($Model, $tempData);
438:         }
439:         $locale = $this->_getLocale($Model);
440: 
441:         foreach ($tempData as $field => $value) {
442:             unset($conditions['content']);
443:             $conditions['field'] = $field;
444:             if (is_array($value)) {
445:                 $conditions['locale'] = array_keys($value);
446:             } else {
447:                 $conditions['locale'] = $locale;
448:                 if (is_array($locale)) {
449:                     $value = array($locale[0] => $value);
450:                 } else {
451:                     $value = array($locale => $value);
452:                 }
453:             }
454:             $translations = $RuntimeModel->find('list', array(
455:                 'conditions' => $conditions,
456:                 'fields' => array(
457:                     $RuntimeModel->alias . '.locale',
458:                     $RuntimeModel->alias . '.id'
459:                 )
460:             ));
461:             foreach ($value as $_locale => $_value) {
462:                 $RuntimeModel->create();
463:                 $conditions['locale'] = $_locale;
464:                 $conditions['content'] = $_value;
465:                 if (array_key_exists($_locale, $translations)) {
466:                     $RuntimeModel->save(array(
467:                         $RuntimeModel->alias => array_merge(
468:                             $conditions, array('id' => $translations[$_locale])
469:                         )
470:                     ));
471:                 } else {
472:                     $RuntimeModel->save(array($RuntimeModel->alias => $conditions));
473:                 }
474:             }
475:         }
476:     }
477: 
478: /**
479:  * Prepares the data to be saved for translated records.
480:  * Add blank fields, and populates data for multi-locale saves.
481:  *
482:  * @param Model $Model Model instance
483:  * @param array $data The sparse data that was provided.
484:  * @return array The fully populated data to save.
485:  */
486:     protected function _prepareTranslations(Model $Model, $data) {
487:         $fields = array_merge($this->settings[$Model->alias], $this->runtime[$Model->alias]['fields']);
488:         $locales = array();
489:         foreach ($data as $key => $value) {
490:             if (is_array($value)) {
491:                 $locales = array_merge($locales, array_keys($value));
492:             }
493:         }
494:         $locales = array_unique($locales);
495:         $hasLocales = count($locales) > 0;
496: 
497:         foreach ($fields as $key => $field) {
498:             if (!is_numeric($key)) {
499:                 $field = $key;
500:             }
501:             if ($hasLocales && !isset($data[$field])) {
502:                 $data[$field] = array_fill_keys($locales, '');
503:             } elseif (!isset($data[$field])) {
504:                 $data[$field] = '';
505:             }
506:         }
507:         return $data;
508:     }
509: 
510: /**
511:  * afterDelete Callback
512:  *
513:  * @param Model $Model Model the callback was run on.
514:  * @return void
515:  */
516:     public function afterDelete(Model $Model) {
517:         $RuntimeModel = $this->translateModel($Model);
518:         $conditions = array('model' => $Model->name, 'foreign_key' => $Model->id);
519:         $RuntimeModel->deleteAll($conditions);
520:     }
521: 
522: /**
523:  * Get selected locale for model
524:  *
525:  * @param Model $Model Model the locale needs to be set/get on.
526:  * @return mixed string or false
527:  */
528:     protected function _getLocale(Model $Model) {
529:         if (!isset($Model->locale) || $Model->locale === null) {
530:             $I18n = I18n::getInstance();
531:             $I18n->l10n->get(Configure::read('Config.language'));
532:             $Model->locale = $I18n->l10n->locale;
533:         }
534: 
535:         return $Model->locale;
536:     }
537: 
538: /**
539:  * Get instance of model for translations.
540:  *
541:  * If the model has a translateModel property set, this will be used as the class
542:  * name to find/use. If no translateModel property is found 'I18nModel' will be used.
543:  *
544:  * @param Model $Model Model to get a translatemodel for.
545:  * @return Model
546:  */
547:     public function translateModel(Model $Model) {
548:         if (!isset($this->runtime[$Model->alias]['model'])) {
549:             if (!isset($Model->translateModel) || empty($Model->translateModel)) {
550:                 $className = 'I18nModel';
551:             } else {
552:                 $className = $Model->translateModel;
553:             }
554: 
555:             $this->runtime[$Model->alias]['model'] = ClassRegistry::init($className);
556:         }
557:         if (!empty($Model->translateTable) && $Model->translateTable !== $this->runtime[$Model->alias]['model']->useTable) {
558:             $this->runtime[$Model->alias]['model']->setSource($Model->translateTable);
559:         } elseif (empty($Model->translateTable) && empty($Model->translateModel)) {
560:             $this->runtime[$Model->alias]['model']->setSource('i18n');
561:         }
562:         return $this->runtime[$Model->alias]['model'];
563:     }
564: 
565: /**
566:  * Bind translation for fields, optionally with hasMany association for
567:  * fake field.
568:  *
569:  * *Note* You should avoid binding translations that overlap existing model properties.
570:  * This can cause un-expected and un-desirable behavior.
571:  *
572:  * @param Model $Model instance of model
573:  * @param string|array $fields string with field or array(field1, field2=>AssocName, field3)
574:  * @param boolean $reset Leave true to have the fields only modified for the next operation.
575:  *   if false the field will be added for all future queries.
576:  * @return boolean
577:  * @throws CakeException when attempting to bind a translating called name. This is not allowed
578:  *   as it shadows Model::$name.
579:  */
580:     public function bindTranslation(Model $Model, $fields, $reset = true) {
581:         if (is_string($fields)) {
582:             $fields = array($fields);
583:         }
584:         $associations = array();
585:         $RuntimeModel = $this->translateModel($Model);
586:         $default = array(
587:             'className' => $RuntimeModel->alias,
588:             'foreignKey' => 'foreign_key'
589:         );
590: 
591:         foreach ($fields as $key => $value) {
592:             if (is_numeric($key)) {
593:                 $field = $value;
594:                 $association = null;
595:             } else {
596:                 $field = $key;
597:                 $association = $value;
598:             }
599:             if ($association === 'name') {
600:                 throw new CakeException(
601:                     __d('cake_dev', 'You cannot bind a translation named "name".')
602:                 );
603:             }
604:             $this->_removeField($Model, $field);
605: 
606:             if ($association === null) {
607:                 if ($reset) {
608:                     $this->runtime[$Model->alias]['fields'][] = $field;
609:                 } else {
610:                     $this->settings[$Model->alias][] = $field;
611:                 }
612:             } else {
613:                 if ($reset) {
614:                     $this->runtime[$Model->alias]['fields'][$field] = $association;
615:                     $this->runtime[$Model->alias]['restoreFields'][] = $field;
616:                 } else {
617:                     $this->settings[$Model->alias][$field] = $association;
618:                 }
619: 
620:                 foreach (array('hasOne', 'hasMany', 'belongsTo', 'hasAndBelongsToMany') as $type) {
621:                     if (isset($Model->{$type}[$association]) || isset($Model->__backAssociation[$type][$association])) {
622:                         trigger_error(
623:                             __d('cake_dev', 'Association %s is already bound to model %s', $association, $Model->alias),
624:                             E_USER_ERROR
625:                         );
626:                         return false;
627:                     }
628:                 }
629:                 $associations[$association] = array_merge($default, array('conditions' => array(
630:                     'model' => $Model->name,
631:                     $RuntimeModel->displayField => $field
632:                 )));
633:             }
634:         }
635: 
636:         if (!empty($associations)) {
637:             $Model->bindModel(array('hasMany' => $associations), $reset);
638:         }
639:         return true;
640:     }
641: 
642: /**
643:  * Update runtime setting for a given field.
644:  *
645:  * @param Model $Model Model instance
646:  * @param string $field The field to update.
647:  * @return void
648:  */
649:     protected function _removeField(Model $Model, $field) {
650:         if (array_key_exists($field, $this->settings[$Model->alias])) {
651:             unset($this->settings[$Model->alias][$field]);
652:         } elseif (in_array($field, $this->settings[$Model->alias])) {
653:             $this->settings[$Model->alias] = array_merge(array_diff($this->settings[$Model->alias], array($field)));
654:         }
655: 
656:         if (array_key_exists($field, $this->runtime[$Model->alias]['fields'])) {
657:             unset($this->runtime[$Model->alias]['fields'][$field]);
658:         } elseif (in_array($field, $this->runtime[$Model->alias]['fields'])) {
659:             $this->runtime[$Model->alias]['fields'] = array_merge(array_diff($this->runtime[$Model->alias]['fields'], array($field)));
660:         }
661:     }
662: 
663: /**
664:  * Unbind translation for fields, optionally unbinds hasMany association for
665:  * fake field
666:  *
667:  * @param Model $Model instance of model
668:  * @param string|array $fields string with field, or array(field1, field2=>AssocName, field3), or null for
669:  *    unbind all original translations
670:  * @return boolean
671:  */
672:     public function unbindTranslation(Model $Model, $fields = null) {
673:         if (empty($fields) && empty($this->settings[$Model->alias])) {
674:             return false;
675:         }
676:         if (empty($fields)) {
677:             return $this->unbindTranslation($Model, $this->settings[$Model->alias]);
678:         }
679: 
680:         if (is_string($fields)) {
681:             $fields = array($fields);
682:         }
683:         $associations = array();
684: 
685:         foreach ($fields as $key => $value) {
686:             if (is_numeric($key)) {
687:                 $field = $value;
688:                 $association = null;
689:             } else {
690:                 $field = $key;
691:                 $association = $value;
692:             }
693: 
694:             $this->_removeField($Model, $field);
695: 
696:             if ($association !== null && (isset($Model->hasMany[$association]) || isset($Model->__backAssociation['hasMany'][$association]))) {
697:                 $associations[] = $association;
698:             }
699:         }
700: 
701:         if (!empty($associations)) {
702:             $Model->unbindModel(array('hasMany' => $associations), false);
703:         }
704:         return true;
705:     }
706: 
707: }
708: 
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