Вы заявили, что хотите сохранить эти данные в формате YAML. В терминологии MVC теперь это ваш источник данных.
Вы можете хранить свои файлы YAML в любом месте системы, но, если вы хотите хранить их под контролем версий и не хотите, чтобы они были общедоступными, подходящее место будет в любом месте в вашем каталоге app/
за пределами app/webroot/
.
Насколько я знаю, в настоящее время не существует каких-либо источников данных, предназначенных для чтения (и / или записи) из файлов YAML, так что это будет делом для вас, если вы хотите строго придерживаться структуры MVC.
Существует несколько примеров источников данных на github и в других местах , на которые вы можете ссылаться. Стоит отметить, что существует два распространенных подхода к созданию источников данных.
- Простой подход (и наиболее распространенный) в основном связан с чтением / записью данных и, как правило, использует в своем источнике данных пользовательские методы, которые может вызывать модель. Это самый быстрый подход, позволяющий получать данные, которые не обязательно должны согласовываться со всеми соглашениями CakePHP.
- Более продвинутый подход (и, возможно, предпочтение разработчикам тортов) заключается в правильном переопределении большинства методов в расширяемом классе (либо DataSource , либо, в случае баз данных, DboSource ). Это позволяет CakePHP творить чудеса при выполнении обычных задач, таких как
find('list')
или paginate()
.
Я бы лично посоветовал начать с простого подхода:
app/config/database.php
:
var $yaml = array(
'datasource' => 'yaml',
'path' => 'data/yaml', // relative to app/ directory, no trailing slash
);
app/models/category.php
// app/models/category.php
class Category extends AppModel {
public $useDbConfig = 'yaml';
/**
* cake should automatically set $model->table to 'categories' on construct
* (http://api.cakephp.org/view_source/model/#l-419) hence $useTable will not
* be necessary (convention over configuration)
*/
// public $useTable = 'categories';
/**
* since datasource doesn't strictly adhere to cake's api, the core find
* method may cause errors. to combat this we can redefine this method with
* a much simpler version, but functionality will be lost in doing so.
*/
public function find($type = 'all', $options = array()) {
// get an instance of our datasource
$ds = ConnectionManager::getDataSource($this->useDbConfig);
// $type is usually handled by model, but we will pass it to datasource
$options['type'] = $type;
// query the datasource
return $ds->read($this, $options);
}
}
app/models/datasources/yaml_source.php
class YamlSource extends DataSource {
public function read(&$model, $queryData = array()) {
// determine path to yaml file
$yamlPath = APP . $this->config['path'] . DS . $model->table . '.yaml';
// parse the yaml file
$results = $this->_parseYaml($yamlPath);
// perform any array manipulation (determined by $queryData)
...
// handle $queryData['type'] (would normally have been done in Model)
...
// return results in a typical Model data array
return array($model->alias => array(
$results // your results go here
));
}
}
app/controllers/categories_controller.php
class PostsController extends AppController {
/**
* this is only needed if all actions use these models. Since Post model is
* loaded automatically, we can just use Controller::loadModel() to get an
* instance of Category model where needed.
*/
//public $uses = array('Post', 'Category');
public function edit($id) {
$posts = $this->Post->read(null, $id);
if (!$post) {
$this->cakeError('error404');
}
$this->loadModel('Category');
$categories = $this->Category->find('list');
$this->set(compact('posts', 'categories'));
}
}
Вы сможете расширять этот источник данных с течением времени (делая его более совместимым с API), так как вам нужны дополнительные функции (нумерация страниц, фильтры обратного вызова, отношения и т. Д.). Этот источник данных будет немедленно повторно использован любыми другими моделями ваших приложений.