Reputation: 428
Let's say I have a model named Reads that contains the following locked schema:
protected $_schema = array(
'_id' => array('type' => 'id'),
'name' => array('type' => 'string', 'unique' => true),
'read_by' => array('type' => 'string', 'array' => true)
);
The "read_by" field actually contains a list of users that have read a particular article. When the model is loaded or ::find() is called, I want it to have another field called "read" that returns true if the currently logged in user's id is found in read_by and false if it is not. Is this possible? I've considered using the ::applyFilter method but am unsure where to go from there.
I'm using Mongo as my db. Thanks.
Edit As per Dave's answer below, the $result object set by $chain->next($self, $params, $chain); in the filter appears like the following:
lithium\data\collection\DocumentSet Object
(
[_original:protected] => Array
(
)
[_parent:protected] =>
[_pathKey:protected] =>
[_model:protected] => app\models\Reads
[_query:protected] => lithium\data\model\Query Object
(
[_map:protected] => Array
(
)
[_entity:protected] =>
[_data:protected] => Array
(
)
[_schema:protected] =>
[_classes:protected] => Array
(
[schema] => lithium\data\Schema
)
[_fields:protected] => Array
(
[0] => Array
(
)
[1] => Array
(
)
)
[_alias:protected] => Array
(
[Reads] => 1
)
[_paths:protected] => Array
(
[Reads] =>
)
[_models:protected] => Array
(
[Reads] => app\models\Reads
)
[_autoConfig:protected] => Array
(
[0] => map
)
[_initializers:protected] => Array
(
[0] => model
[1] => entity
[2] => conditions
[3] => having
[4] => group
[5] => order
[6] => limit
[7] => offset
[8] => page
[9] => data
[10] => calculate
[11] => schema
[12] => comment
)
[_built:protected] => 1
[_config:protected] => Array
(
[conditions] => Array
(
[feed_id] => Array
(
[$in] => Array
(
[0] => MongoId Object
(
[$id] => 51b79acbac53cfb51645ffa7
)
)
)
[read_by] => Array
(
[$nin] => Array
(
[0] => 51592dcc6d6d877c0a000002
)
)
)
[order] => Array
(
[date_added] => DESC
)
[limit] => 25
[user] => 51592dcc6d6d877c0a000002
[fields] =>
[page] =>
[with] => Array
(
)
[type] => read
[model] => app\models\Reads
[mode] =>
[source] => reads
[alias] => Reads
[having] => Array
(
)
[group] =>
[offset] =>
[joins] => Array
(
)
[data] => Array
(
)
[whitelist] => Array
(
)
[calculate] =>
[schema] =>
[comment] =>
[map] => Array
(
)
[relationships] => Array
(
)
)
[_methodFilters:protected] => Array
(
)
)
[_result:protected] => lithium\data\source\mongo_db\Result Object
(
[_cache:protected] =>
[_iterator:protected] => 0
[_current:protected] =>
[_started:protected] =>
[_init:protected] =>
[_valid:protected] =>
[_key:protected] =>
[_resource:protected] => MongoCursor Object
(
)
[_autoConfig:protected] => Array
(
[0] => resource
)
[_config:protected] => Array
(
[resource] => MongoCursor Object
(
)
[init] => 1
)
[_methodFilters:protected] => Array
(
)
)
[_valid:protected] => 1
[_stats:protected] => Array
(
)
[_started:protected] =>
[_exists:protected] =>
[_schema:protected] =>
[_autoConfig:protected] => Array
(
[0] => model
[1] => result
[2] => query
[3] => parent
[4] => stats
[5] => pathKey
[6] => exists
[7] => schema
)
[_data:protected] => Array
(
)
[_config:protected] => Array
(
[init] => 1
)
[_methodFilters:protected] => Array
(
)
)
Upvotes: 0
Views: 136
Reputation: 53
In your Reads model, you could define the find
filter in the __init()
function:
public static function __init() {
static::applyFilter('find', function($self, $params, $chain) {
//get the find result
$result = $chain->next($self, $params, $chain);
//set default of 'read' field to false
$read = false;
//check if user is in 'read_by' array
if (isset($params['user']) && isset($result->read_by)) {
$read = in_array($params['user'], $result->read_by) ? true : false;
});
$result->read = $read;
return $result;
}
}
Then provide the matching User id or name, or whatever you're storing in the read_by
array, when you run the find:
$reads = Reads::find('first', ['user' => 'username']);
(I'm using PHP 5.4 array syntax in these examples.)
Upvotes: 1