/** * Gets a representation of the elements in the tree as a flat list where the keys are * the primary key for the table and the values are the display field for the table. * Values are prefixed to visually indicate relative depth in the tree. * * Avaliable options are: * * - keyPath: A dot separated path to fetch the field to use for the array key, or a closure to * return the key out of the provided row. * - valuePath: A dot separated path to fetch the field to use for the array value, or a closure to * return the value out of the provided row. * - spacer: A string to be used as prefix for denoting the depth in the tree for each item * * @param \Cake\ORM\Query $query * @param array $options Array of options as described above * @return \Cake\ORM\Query */ public function findTreeList(Query $query, array $options) { return $this->_scope($query)->find('threaded', ['parentField' => $this->config()['parent']])->formatResults(function ($results) use($options) { $options += ['keyPath' => $this->_table->primaryKey(), 'valuePath' => $this->_table->displayField(), 'spacer' => '_']; return $results->listNested()->printer($options['valuePath'], $options['keyPath'], $options['spacer']); }); }
/** * ResetSlugs method. * * Regenerate all slugs. On large dbs this can take more than 30 seconds - a time * limit is set to allow a minimum 100 updates per second as a preventative measure. * * Note that you should use the Reset behavior if you need additional functionality such * as callbacks or timeouts. * * @param array $params * @return bool Success */ public function resetSlugs($params = []) { if (!$this->_table->hasField($this->_config['field'])) { throw new Exception('Table does not have field ' . $this->_config['field']); } $defaults = ['page' => 1, 'limit' => 100, 'fields' => array_merge([$this->_table->primaryKey()], $this->_config['label']), 'order' => $this->_table->displayField() . ' ASC', 'conditions' => $this->_config['scope'], 'overwrite' => true]; $params = array_merge($defaults, $params); $count = $this->_table->find('all', compact('conditions'))->count(); $max = ini_get('max_execution_time'); if ($max) { set_time_limit(max($max, $count / 100)); } $this->_table->behaviors()->Slugged->config($params, null, false); while ($records = $this->_table->find('all', $params)->toArray()) { foreach ($records as $record) { $record->isNew(true); $options = ['validate' => true, 'fieldList' => array_merge([$this->_table->primaryKey(), $this->_config['field']], $this->_config['label'])]; if (!$this->_table->save($record, $options)) { throw new Exception(print_r($this->_table->errors(), true)); } } $params['page']++; } return true; }
/** * Tests find('list') with hydrated records * * @return void */ public function testFindListHydrated() { $table = new Table(['table' => 'users', 'connection' => $this->connection]); $table->displayField('username'); $query = $table->find('list', ['fields' => ['id', 'username']])->order('id'); $expected = [1 => 'mariano', 2 => 'nate', 3 => 'larry', 4 => 'garrett']; $this->assertSame($expected, $query->toArray()); $query = $table->find('list', ['groupField' => 'odd'])->select(['id', 'username', 'odd' => new FunctionExpression('MOD', [new IdentifierExpression('id'), 2])])->hydrate(true)->order('id'); $expected = [1 => [1 => 'mariano', 3 => 'larry'], 0 => [2 => 'nate', 4 => 'garrett']]; $this->assertSame($expected, $query->toArray()); }
/** * Get the display field from the model or parameters * * @param \Cake\ORM\Table $model The model to introspect. * @return string */ public function getDisplayField($model) { if (!empty($this->params['display-field'])) { return $this->params['display-field']; } return $model->displayField(); }
/** * Tests find('list') with composite keys * * @return void */ public function testFindListCompositeKeys() { $table = new Table(['table' => 'site_authors', 'connection' => $this->connection]); $table->displayField('name'); $query = $table->find('list')->hydrate(false)->order('id'); $expected = ['1;1' => 'mark', '2;2' => 'juan', '3;2' => 'jose', '4;1' => 'andy']; $this->assertEquals($expected, $query->toArray()); $table->displayField(['name', 'site_id']); $query = $table->find('list')->hydrate(false)->order('id'); $expected = ['1;1' => 'mark;1', '2;2' => 'juan;2', '3;2' => 'jose;2', '4;1' => 'andy;1']; $this->assertEquals($expected, $query->toArray()); $query = $table->find('list', ['groupField' => ['site_id', 'site_id']])->hydrate(false)->order('id'); $expected = ['1;1' => ['1;1' => 'mark;1', '4;1' => 'andy;1'], '2;2' => ['2;2' => 'juan;2', '3;2' => 'jose;2']]; $this->assertEquals($expected, $query->toArray()); }
/** * test that find('list') does not auto add fields to select if using virtual properties * * @return void */ public function testFindListWithVirtualField() { $table = new Table(['table' => 'users', 'connection' => $this->connection, 'entityClass' => '\\TestApp\\Model\\Entity\\VirtualUser']); $table->displayField('bonus'); $query = $table->find('list')->order('id'); $this->assertEmpty($query->clause('select')); $expected = [1 => 'bonus', 2 => 'bonus', 3 => 'bonus', 4 => 'bonus']; $this->assertSame($expected, $query->toArray()); $query = $table->find('list', ['groupField' => 'odd']); $this->assertEmpty($query->clause('select')); }
/** * Assert MPTT values * * Custom assert method to make identifying the differences between expected * and actual db state easier to identify. * * @param array $expected tree state to be expected * @param \Cake\ORM\Table $table Table instance * @param \Cake\ORM\Query $query Optional query object * @return void */ public function assertMpttValues($expected, $table, $query = null) { $query = $query ?: $table->find(); $primaryKey = $table->primaryKey(); if (is_array($primaryKey)) { $primaryKey = $primaryKey[0]; } $displayField = $table->displayField(); $options = ['valuePath' => function ($item, $key, $iterator) use($primaryKey, $displayField) { return sprintf('%s:%s - %s:%s', str_pad($item->lft, 2, ' ', STR_PAD_LEFT), str_pad($item->rght, 2, ' ', STR_PAD_LEFT), str_pad($item->{$primaryKey}, 2, ' ', STR_PAD_LEFT), $item->{$displayField}); }]; $result = array_values($query->find('treeList', $options)->toArray()); if (count($result) === count($expected)) { $subExpected = array_diff($expected, $result); if ($subExpected) { $subResult = array_intersect_key($result, $subExpected); $this->assertSame($subExpected, $subResult, 'Differences in the tree were found (lft:rght id:display-name)'); } } $this->assertSame($expected, $result, 'The tree is not the same (lft:rght id:display-name)'); }