Пример #1
0
 /**
  * Returns false if the node fails to match the parameters
  *
  * @throws NodeException
  * @param  $node
  * @param  $filterParams
  * @param  $metaParams
  * @return bool
  */
 protected function filterNode($node, $filterParams, $metaParams)
 {
     if (!empty($filterParams)) {
         if (is_null($this->now)) {
             $this->now = $this->DateFactory->newStorageDate();
         }
         foreach ($filterParams as $key => $value) {
             if (strpos($key, '#') === 0) {
                 continue;
             }
             switch ($key) {
                 case 'Title.firstChar':
                     $firstChar = strtolower(substr($node['Title'], 0, 1));
                     if ($value == '#') {
                         $ord = ord($firstChar);
                         if ($ord >= 97 && $ord <= 122) {
                             return false;
                         }
                     } else {
                         if (strcmp($firstChar, $value) !== 0) {
                             return false;
                         }
                     }
                     break;
                 case 'Title.eq':
                     if (strcmp($value, $node['Title']) !== 0) {
                         return false;
                     }
                     break;
                 case 'Title.ieq':
                     if (strcasecmp($value, $node['Title']) !== 0) {
                         return false;
                     }
                     break;
                 case 'Title.like':
                     if (is_null($value)) {
                         break;
                     }
                     if (stripos($node['Title'], $value) === FALSE) {
                         return false;
                     }
                     break;
                 case 'TreeID.childOf':
                     if (stripos($node['TreeID'], $value) !== 0) {
                         return false;
                     }
                     break;
                 case 'TreeID.eq':
                     if (strcmp($value, $node['TreeID']) !== 0) {
                         return false;
                     }
                     break;
                 case 'TreeID.depth':
                     if (strlen($node['TreeID']) / 4 != $value) {
                         return false;
                     }
                     break;
                 case 'ActiveDate.after':
                     if ($node['ActiveDate']->toUnix() < $value->toUnix()) {
                         return false;
                     }
                     break;
                 case 'ActiveDate.before':
                     if ($node['ActiveDate']->toUnix() >= $value->toUnix()) {
                         return false;
                     }
                     break;
                 case 'ActiveDate.start':
                     if ($node['ActiveDate']->toUnix() <= $value->toUnix()) {
                         return false;
                     }
                     break;
                 case 'ActiveDate.end':
                     if ($node['ActiveDate']->toUnix() >= $value->toUnix()) {
                         return false;
                     }
                     break;
                 case 'CreationDate.after':
                     if ($node['CreationDate']->toUnix() < $value->toUnix()) {
                         return false;
                     }
                     break;
                 case 'CreationDate.before':
                     if ($node['CreationDate']->toUnix() >= $value->toUnix()) {
                         return false;
                     }
                     break;
                 case 'CreationDate.start':
                     if ($node['CreationDate']->toUnix() <= $value->toUnix()) {
                         return false;
                     }
                     break;
                 case 'CreationDate.end':
                     if ($node['CreationDate']->toUnix() >= $value->toUnix()) {
                         return false;
                     }
                     break;
                 case 'Status.eq':
                     switch (strtolower($value)) {
                         case 'published':
                             if (strtolower($node['Status']) != 'published') {
                                 return false;
                             }
                             break;
                         case 'draft':
                             if (strtolower($node['Status']) != 'draft') {
                                 return false;
                             }
                             break;
                         case 'deleted':
                             if (strtolower($node['Status']) != 'deleted') {
                                 return false;
                             }
                             break;
                         default:
                             if (strtolower($node['Status']) == 'deleted') {
                                 return false;
                             }
                             break;
                     }
                     break;
                 case 'Status.isActive':
                     if (StringUtils::strToBool($value) == true && (strcmp('published', $node['Status']) !== 0 || $node['ActiveDate']->toUnix() >= $this->now->toUnix())) {
                         return false;
                     }
                     break;
                 case 'Status.all':
                     if (StringUtils::strToBool($value) == false && strcmp('deleted', $node['Status']) === 0) {
                         return false;
                     }
                     break;
                     //                case 'IncludesMeta':
                     //                    $found = false;
                     //                    foreach($value as $partial) {
                     //                        $meta = MetaUtils::filterMeta($node['Metas'],$partial->getMetaName());
                     //                        if($partial->match($meta))
                     //                            $found = true;
                     //                    }
                     //                    if(!$found)
                     //                        return false;
                     //                    break;
                 //                case 'IncludesMeta':
                 //                    $found = false;
                 //                    foreach($value as $partial) {
                 //                        $meta = MetaUtils::filterMeta($node['Metas'],$partial->getMetaName());
                 //                        if($partial->match($meta))
                 //                            $found = true;
                 //                    }
                 //                    if(!$found)
                 //                        return false;
                 //                    break;
                 case 'Meta.exist':
                     foreach ($value as $partial) {
                         $meta = $node->getMeta($partial->getMetaName());
                         if (empty($meta) || !$partial->match($meta)) {
                             return false;
                         }
                     }
                     break;
                     //                case 'IncludesOutTags':
                     //                    $found = false;
                     //                    foreach($value as $partial) {
                     //                        foreach($node['OutTags'] as $tag)
                     //                        {
                     //                            if($this->TagsHelper->matchPartial($partial, $tag)) {
                     //                                $found = true;
                     //                                break 2;
                     //                            }
                     //                        }
                     //                    }
                     //                    if(!$found)
                     //                        return false;
                     //
                     //                    break;
                 //                case 'IncludesOutTags':
                 //                    $found = false;
                 //                    foreach($value as $partial) {
                 //                        foreach($node['OutTags'] as $tag)
                 //                        {
                 //                            if($this->TagsHelper->matchPartial($partial, $tag)) {
                 //                                $found = true;
                 //                                break 2;
                 //                            }
                 //                        }
                 //                    }
                 //                    if(!$found)
                 //                        return false;
                 //
                 //                    break;
                 case 'OutTags.exist':
                     $found = 0;
                     foreach ($value as $partial) {
                         foreach ($node['OutTags'] as $tag) {
                             if ($this->TagsHelper->matchPartial($partial, $tag)) {
                                 ++$found;
                                 break;
                             }
                         }
                     }
                     if ($found != count($value)) {
                         return false;
                     }
                     break;
                     //                case 'IncludesInTags':
                     //                    $found = false;
                     //                    foreach($value as $partial) {
                     //                        foreach($node['InTags'] as $tag)
                     //                        {
                     //                            if($this->TagsHelper->matchPartial($partial, $tag)) {
                     //                                $found = true;
                     //                                break 2;
                     //                            }
                     //                        }
                     //                    }
                     //                    if(!$found)
                     //                        return false;
                     //
                     //                    break;
                 //                case 'IncludesInTags':
                 //                    $found = false;
                 //                    foreach($value as $partial) {
                 //                        foreach($node['InTags'] as $tag)
                 //                        {
                 //                            if($this->TagsHelper->matchPartial($partial, $tag)) {
                 //                                $found = true;
                 //                                break 2;
                 //                            }
                 //                        }
                 //                    }
                 //                    if(!$found)
                 //                        return false;
                 //
                 //                    break;
                 case 'InTags.exist':
                     $found = 0;
                     foreach ($value as $partial) {
                         foreach ($node['InTags'] as $tag) {
                             if ($this->TagsHelper->matchPartial($partial, $tag)) {
                                 ++$found;
                                 break;
                             }
                         }
                     }
                     if ($found != count($value)) {
                         return false;
                     }
                     break;
             }
         }
     }
     if (!empty($metaParams)) {
         $schema = $node['NodeRef']->getElement()->getSchema();
         foreach ($metaParams as $mArgs) {
             list($full, $name, $operator, $compareValue) = $mArgs;
             $def = $schema->getMetaDef($name);
             $datatype = $def->Datatype;
             if (is_object($node)) {
                 $realValue = $node->getMetaValue($name);
             } else {
                 $meta = MetaUtils::filterMeta($node['Metas'], $name);
                 $realValue = $meta->getMetaValue();
             }
             if ($datatype == 'flag') {
                 throw new NodeException('Unable to run meta clause on flag datatype');
             }
             switch ($operator) {
                 case 'eq':
                     if (in_array($datatype, array('text', 'varchar'))) {
                         if (strcmp($compareValue, $realValue) !== 0) {
                             return false;
                         } else {
                             if ($compareValue !== $realValue) {
                                 return false;
                             }
                         }
                     }
                     break;
                 case 'ieq':
                     if (strcasecmp($compareValue, $realValue) !== 0) {
                         return false;
                     }
                     break;
                 case 'like':
                     if (is_null($compareValue)) {
                         break;
                     }
                     if (stripos($compareValue, $realValue) === FALSE) {
                         return false;
                     }
                     break;
                 case 'before':
                     $d = $this->DateFactory->newLocalDate($value);
                     if ($realValue->toUnix() <= $d->toUnix()) {
                         return false;
                     }
                     break;
                 case 'after':
                     $d = $this->DateFactory->newLocalDate($compareValue);
                     if ($realValue->toUnix() > $d->toUnix()) {
                         return false;
                     }
                     break;
                 case 'start':
                     $d = $this->DateFactory->newLocalDate($compareValue);
                     $d->setTime(0, 0, 0);
                     if ($realValue->toUnix() >= $d->toUnix()) {
                         return false;
                     }
                     break;
                 case 'end':
                     $d = $this->DateFactory->newLocalDate($compareValue);
                     $d->setTime(23, 59, 59);
                     if ($realValue->toUnix() <= $d->toUnix()) {
                         return false;
                     }
                     break;
                 case 'notEq':
                     if (in_array($datatype, array('text', 'varchar'))) {
                         if (strcmp($compareValue, $realValue) === 0) {
                             return false;
                         } else {
                             if ($compareValue === $realValue) {
                                 return false;
                             }
                         }
                     }
                     break;
                 case 'lessThan':
                     if ($compareValue >= $realValue) {
                         return false;
                     }
                     break;
                 case 'lessThanEq':
                     if ($compareValue > $realValue) {
                         return false;
                     }
                     break;
                 case 'greaterThan':
                     if ($compareValue <= $realValue) {
                         return false;
                     }
                     break;
                 case 'greaterThanEq':
                     if ($compareValue < $realValue) {
                         return false;
                     }
                     break;
                     /*
                      * case insensitive comparison for #meta.in filtering.
                      * works exactly like the SQL SomeValue IN ('item1', 'item2')
                      */
                 /*
                  * case insensitive comparison for #meta.in filtering.
                  * works exactly like the SQL SomeValue IN ('item1', 'item2')
                  */
                 case 'in':
                     $inValues = explode(',', $compareValue);
                     $foundValue = false;
                     if (in_array($datatype, array('text', 'varchar'))) {
                         foreach ($inValues as $val) {
                             if (strcasecmp($val, $realValue) === 0) {
                                 $foundValue = true;
                                 break;
                             }
                         }
                     } else {
                         foreach ($inValues as $val) {
                             if ($val === $realValue) {
                                 $foundValue = true;
                                 break;
                             }
                         }
                     }
                     if (!$foundValue) {
                         return false;
                     }
                     break;
             }
         }
     }
     return true;
 }
Пример #2
0
 public function saveMeta(DatabaseInterface $db, NodeRef $originNodeRef, $recordid, $metaPartials = 'fields', array $metaTags, $restrictedPartials = '')
 {
     if (empty($recordid)) {
         throw new Exception('Cannot save meta without recordid');
     }
     $originalRestrictedPartials = $restrictedPartials;
     $restrictedPartials = PartialUtils::unserializeMetaPartials($restrictedPartials);
     if ($restrictedPartials == 'all' || ($x = array_search('all', $restrictedPartials)) !== false) {
         return;
     }
     MetaUtils::validateMeta($metaTags);
     //        $originNodeRef = $node->getNodeRef();
     $tableid = $this->NodeDBMeta->getPrimaryKey($originNodeRef);
     $now = $this->DateFactory->newStorageDate();
     $tagsToDelete = array();
     $updatedMeta = array();
     $originalMeta = array();
     //        if($sectionType != null)
     //        {
     //            $schema = $originNodeRef->getElement()->getSchema()->getSectionDef($sectionType);
     //        } else
     //        {
     $schema = $originNodeRef->getElement()->getSchema();
     //        }
     // remove duplicates from meta
     foreach ($metaTags as $o => &$mtag) {
         //            if($sectionid != 0)
         //                $mtag->setMetaSectionID($sectionid);
         $metaDef = $schema->getMetaDef($mtag->getMetaName());
         $mtag->setMetaStorageDatatype($metaDef->Datatype);
         $mtag->setMetaValidationDatatype($metaDef->Validation->getDatatype());
         foreach ($metaTags as $i => $ddtag) {
             //if($o != $i && $tag->getMetaName() === $dtag->getMetaName() && $tag->getMetaSectionID() == $dtag->getMetaSectionID())
             if ($o != $i && $mtag->getMetaName() === $ddtag->getMetaName()) {
                 //                  error_log("REMOVING DUPE ".$dtag->toString());
                 unset($metaTags[$o]);
             }
         }
         foreach ($restrictedPartials as $dPartial) {
             if (strcmp($dPartial->getMetaName(), $mtag['MetaName']) === 0) {
                 unset($metaTags[$o]);
             }
         }
     }
     $currentMetaTags = $this->findMeta($db, $originNodeRef, $recordid, $metaPartials, true, $originalRestrictedPartials);
     //        $this->Logger->debug('current meta for ['.$recordid.'] on section ['.$sectionid.']');
     //        $this->Logger->debug($currentMetaTags);
     MetaUtils::validateMeta($currentMetaTags);
     foreach ($currentMetaTags as $k => $tag) {
         //if($tag->getMetaID() == false) throw new Exception('Cannot save meta without MetaIDs for current meta');
         $foundThisTag = false;
         foreach ($metaTags as $dtag) {
             //if($tag->getMetaName() === $dtag->getMetaName() && $tag->getMetaSectionID() == $dtag->getMetaSectionID())
             if ($tag->getMetaName() === $dtag->getMetaName()) {
                 //                  error_log("MATCHED ".$dtag->toString() ." TO ".$tag->toString());
                 //                  error_log(print_r($dtag, true));
                 //                  error_log(print_r($tag, true));
                 // delete string meta that have no value
                 if (($dtag->getMetaStorageDatatype() == 'text' || $dtag->getMetaStorageDatatype() == 'varchar' || $dtag->getMetaStorageDatatype() == 'blob') && strlen(trim($dtag->getMetaValue())) == 0 || $dtag->getMetaStorageDatatype() == 'flag' && $dtag->getMetaValue() == false || ($dtag->getMetaValidationDatatype() == 'int' || $dtag->getMetaValidationDatatype() == 'float') && $dtag->getMetaValue() === null || in_array($dtag, $updatedMeta)) {
                     //                            error_log('DELETE: '.$tag);
                     $tagsToDelete[] = $tag;
                 } else {
                     //                        error_log('UPDATE: '.$tag);
                     $updatedMeta[$tag->getMetaStorageDatatype()][] = $dtag;
                     $originalMeta[$tag->getMetaStorageDatatype()][] = $tag;
                 }
                 $foundThisTag = true;
                 break;
             }
         }
         if (!$foundThisTag) {
             $tagsToDelete[] = $tag;
         }
     }
     $changedOne = false;
     $tagIDsToDelete = array();
     foreach ($tagsToDelete as $tag) {
         // log tag deletion
         //            $this->transactionsService->logMetaDelete($element, $recordid, $tag);
         $table = $this->NodeDBMeta->getMetaTable($originNodeRef, $tag->getMetaStorageDatatype());
         $affectedRows = $db->deleteRecord($table, "{$tableid} = {$db->quote($recordid)} AND Name = {$db->quote($tag->getMetaName())}");
         if ($affectedRows > 0) {
             $this->NodeEvents->fireMetaEvents('meta', 'remove', $originNodeRef, $tag);
             $changedOne = true;
         }
         //            $tagIDsToDelete[][] = $tag->getMetaID();
     }
     //        if(!empty($tagIDsToDelete)){
     //            foreach($tagIDsToDelete as $datatype => $ids){
     //
     //                ;
     //                $deletions = $db->write("DELETE FROM {$db->quoteIdentifier($table)} WHERE MetaID IN (".$db->joinQuote((array)$ids).")", DatabaseInterface::AFFECTED_ROWS);
     //
     //            }
     //        }
     foreach ($metaTags as $tag) {
         $datatype = $tag->getMetaStorageDatatype();
         $table = $db->quoteIdentifier($this->NodeDBMeta->getMetaTable($originNodeRef, $datatype));
         if (($datatype == 'text' || $datatype == 'varchar' || $datatype == 'blob') && strlen(trim($tag->getMetaValue())) == 0) {
             continue;
         }
         if ($datatype == 'flag' && $tag->getMetaValue() == false) {
             continue;
         }
         if (($tag->getMetaValidationDatatype() == 'int' || $tag->getMetaValidationDatatype() == 'float') && $tag->getMetaValue() === null) {
             continue;
         }
         $datatypeCol = $this->NodeDBMeta->getMetaDatatypeColumn($datatype);
         if (isset($updatedMeta[$datatype]) && in_array($tag, $updatedMeta[$datatype])) {
             $tagid = array_search($tag, $updatedMeta[$datatype]);
             $originalTag = $originalMeta[$datatype][$tagid];
             // if this is an integer storage field and the originalvalue is 0 and the new value equates to 0, do no update
             if (in_array(strtolower($datatypeCol), array('tiny', 'int', 'long', 'float')) && floatVal($originalTag->getMetaValue()) == 0 && floatVal($tag->getMetaValue()) == 0) {
                 continue;
             }
             if ($datatype != 'flag' && strcmp('' . $originalTag->getMetaValue(), '' . $tag->getMetaValue()) !== 0) {
                 // update the meta tag
                 $affectedRows = $db->updateRecord($table, array("{$datatypeCol}Value" => $tag->getMetaValue()), "{$tableid} = {$db->quote($recordid)} AND Name = {$db->quote($tag->getMetaName())}");
                 if ($affectedRows > 0) {
                     $this->NodeEvents->fireMetaEvents('meta', 'update', $originNodeRef, $tag, $originalTag);
                     //                        if($tag->getMetaValidationDatatype() == 'boolean')
                     //                            if($tag->getMetaValue() == false)
                     //                                $this->NodeEvents->fireMetaEvents('meta', 'remove', $originNodeRef, $tag, $originalTag);
                     //                            else
                     //                                $this->NodeEvents->fireMetaEvents('meta', 'add', $originNodeRef, $tag, $originalTag);
                     $changedOne = true;
                 }
             }
         } else {
             // insert the meta tag
             //                $newinsert = array(
             //                    $tableid => $recordid,
             //                    'Name' => $tag->getMetaName(),
             //                    "{$datatype}Value" => $tag->getMetaValue(),
             //                );
             try {
                 if ($datatype == 'flag') {
                     $affectedRows = $db->write("INSERT IGNORE INTO {$table} ({$tableid}, Name) Values ({$db->quote($recordid)}, {$db->quote($tag->getMetaName())})", DatabaseInterface::AFFECTED_ROWS);
                 } else {
                     $affectedRows = $db->write("INSERT INTO {$table} ({$tableid}, Name, {$datatypeCol}Value) Values ({$db->quote($recordid)}, {$db->quote($tag->getMetaName())}, {$db->quote($tag->getMetaValue())})", DatabaseInterface::AFFECTED_ROWS);
                 }
                 //                $bulkTagInserts[$datatype][] = $newinsert;
                 //                $db->insertRecord($table, $newinsert);
                 if ($affectedRows > 0) {
                     $this->NodeEvents->fireMetaEvents('meta', 'add', $originNodeRef, $tag);
                     $changedOne = true;
                 }
             } catch (SQLDuplicateKeyException $dke) {
                 $where = "{$tableid} = {$db->quote($recordid)} AND Name = {$db->quote($tag->getMetaName())}";
                 $originalValue = $db->readField("SELECT {$datatypeCol}Value FROM {$table} WHERE {$where} LOCK IN SHARE MODE");
                 // update the meta tag
                 $affectedRows = $db->updateRecord($table, array("{$datatypeCol}Value" => $tag->getMetaValue()), $where);
                 if ($affectedRows > 0) {
                     $this->NodeEvents->fireMetaEvents('meta', 'update', $originNodeRef, $tag, new Meta($tag->getMetaName(), $originalValue));
                     $changedOne = true;
                 }
             }
             //                $this->NodeEvents->fireMetaEvents('meta', 'add', $originNodeRef, $tag);
         }
     }
     //        if(!empty($bulkTagInserts))
     //            foreach($bulkTagInserts as $datatype => $bulkInserts)
     //                $db->bulkInsertRecords($db->quoteIdentifier($this->NodeDBMeta->getMetaTable($originNodeRef, $datatype)), $bulkInserts);
     return $changedOne;
 }