FOF30\Model\DataModel\Relation\BelongsToMany::filterForeignModel PHP Method

filterForeignModel() protected method

Applies the relation filters to the foreign model when getData is called
protected filterForeignModel ( DataModel $foreignModel, Collection $dataCollection = null ) : boolean
$foreignModel FOF30\Model\DataModel The foreign model you're operating on
$dataCollection FOF30\Model\DataModel\Collection If it's an eager loaded relation, the collection of loaded parent records
return boolean Return false to force an empty data collection
    protected function filterForeignModel(DataModel $foreignModel, DataModel\Collection $dataCollection = null)
    {
        $db = $this->parentModel->getDbo();
        // Decide how to proceed, based on eager or lazy loading
        if (is_object($dataCollection)) {
            // Eager loaded relation
            if (!empty($dataCollection)) {
                // Get a list of local keys from the collection
                $values = array();
                /** @var $item DataModel */
                foreach ($dataCollection as $item) {
                    $v = $item->getFieldValue($this->localKey, null);
                    if (!is_null($v)) {
                        $values[] = $v;
                    }
                }
                // Keep only unique values
                $values = array_unique($values);
                $values = array_map(function ($x) use(&$db) {
                    return $db->q($x);
                }, $values);
                // Get the foreign keys from the glue table
                $query = $db->getQuery(true)->select(array($db->qn($this->pivotLocalKey), $db->qn($this->pivotForeignKey)))->from($db->qn($this->pivotTable))->where($db->qn($this->pivotLocalKey) . ' IN(' . implode(',', $values) . ')');
                $db->setQuery($query);
                $foreignKeysUnmapped = $db->loadRowList();
                $this->foreignKeyMap = array();
                $foreignKeys = array();
                foreach ($foreignKeysUnmapped as $unmapped) {
                    $local = $unmapped[0];
                    $foreign = $unmapped[1];
                    if (!isset($this->foreignKeyMap[$local])) {
                        $this->foreignKeyMap[$local] = array();
                    }
                    $this->foreignKeyMap[$local][] = $foreign;
                    $foreignKeys[] = $foreign;
                }
                // Keep only unique values. However, the array keys are all screwed up. See below.
                $foreignKeys = array_unique($foreignKeys);
                // This looks stupid, but it's required to reset the array keys. Without it where() below fails.
                $foreignKeys = array_merge($foreignKeys);
                // Apply the filter
                if (!empty($foreignKeys)) {
                    $foreignModel->where($this->foreignKey, 'in', $foreignKeys);
                } else {
                    return false;
                }
            } else {
                return false;
            }
        } else {
            // Lazy loaded relation; get the single local key
            $localKey = $this->parentModel->getFieldValue($this->localKey, null);
            if (is_null($localKey)) {
                return false;
            }
            $query = $db->getQuery(true)->select($db->qn($this->pivotForeignKey))->from($db->qn($this->pivotTable))->where($db->qn($this->pivotLocalKey) . ' = ' . $db->q($localKey));
            $db->setQuery($query);
            $foreignKeys = $db->loadColumn();
            $this->foreignKeyMap[$localKey] = $foreignKeys;
            // If there are no foreign keys (no foreign items assigned to our item) we return false which then causes
            // the relation to return null, marking the lack of data.
            if (empty($foreignKeys)) {
                return false;
            }
            $foreignModel->where($this->foreignKey, 'in', $this->foreignKeyMap[$localKey]);
        }
        return true;
    }