/** * Retrieves all virtual values of all the entities within the given result-set. * * @param \Cake\Collection\CollectionInterface $entities Set of entities * @param array $args Contains two keys: "options" and "primary" given to the * originating beforeFind(), and "selectedVirtual" a list of virtual columns * selected in the originating find query * @return array Virtual values indexed by entity ID */ protected function _prepareSetValues(CollectionInterface $entities, array $args) { $entityIds = $this->_toolbox->extractEntityIds($entities); if (empty($entityIds)) { return []; } $selectedVirtual = $args['selectedVirtual']; $bundle = $args['options']['bundle']; $validColumns = array_values($selectedVirtual); $validNames = array_intersect($this->_toolbox->getAttributeNames($bundle), $validColumns); $attrsById = []; foreach ($this->_toolbox->attributes($bundle) as $name => $attr) { if (in_array($name, $validNames)) { $attrsById[$attr['id']] = $attr; } } if (empty($attrsById)) { return []; } return TableRegistry::get('Eav.EavValues')->find('all')->bufferResults(false)->where(['EavValues.eav_attribute_id IN' => array_keys($attrsById), 'EavValues.entity_id IN' => $entityIds])->all()->map(function ($value) use($attrsById, $selectedVirtual) { $attrName = $attrsById[$value->get('eav_attribute_id')]->get('name'); $attrType = $attrsById[$value->get('eav_attribute_id')]->get('type'); $alias = array_search($attrName, $selectedVirtual); return ['entity_id' => $value->get('entity_id'), 'property_name' => is_string($alias) ? $alias : $attrName, 'value' => $this->_toolbox->marshal($value->get("value_{$attrType}"), $attrType)]; })->groupBy('entity_id')->toArray(); }