<?php
/**
* @package Habari
*
*/
/**
* Habari Terms Class
* Holds multiple Term object instances in an array-like structure,
* for the purpose of acting on them en-masse, or testing against them.
*
*/
class Terms extends ArrayObject implements FormStorage
{
/**
* See if a term or set of terms is in this set of terms
*
* @param mixed $tags. A string containing a string or a comma separated list of strings,
* or an array of strings, Terms, or a Term subclass
* @return boolean. Whether the tag(s) is in the current set of tags.
*/
public function has( $tags )
{
if ( is_string( $tags ) || ( is_array( $tags ) && is_string( $tags[0] ) ) ) {
$tags = (array)Terms::parse( $tags );
}
$diff = array_diff( $tags, (array)$this );
foreach ( $tags as $tag ) {
if ( in_array( $tag, $diff ) ) {
return false;
}
}
return true;
}
/**
* Turns a comma-separated string or array of terms into an array of Term objects
* @param mixed $terms A comma-separated string or array of string terms
* @param string $term_class The class of the Term object type to create from each string
* @param Vocabulary $vocabulary An instance of the Vocabulary that might hold the terms.
* Use existing term object data if found in the specified vocabulary.
* @return Terms An instance of Terms contianing the specified Term objects
**/
public static function parse( $terms, $term_class = 'Term', $vocabulary = null )
{
if ( is_string( $terms ) ) {
if ( '' === $terms ) {
return new Terms();
}
// dirrty ;)
$rez = array( '\\"'=>':__unlikely_quote__:', '\\\''=>':__unlikely_apos__:' );
$zer = array( ':__unlikely_quote__:'=>'"', ':__unlikely_apos__:'=>"'" );
// escape
$tagstr = str_replace( array_keys( $rez ), $rez, $terms );
// match-o-matic
preg_match_all( '/((("|((?<= )|^)\')\\S([^\\3]*?)\\3((?=[\\W])|$))|[^,])+/u', $tagstr, $matches );
// cleanup
$terms = array_map( 'trim', $matches[0] );
$terms = preg_replace( array_fill( 0, count( $terms ), '/^(["\'])(((?!").)+)(\\1)$/' ), '$2', $terms );
// unescape
$terms = str_replace( array_keys( $zer ), $zer, $terms );
// hooray
}
if ( is_array( $terms ) ) {
if ( $vocabulary instanceof Vocabulary ) {
foreach ( $terms as $k => $term ) {
if ( $saved_term = $vocabulary->get_term( $term, $term_class ) ) {
$terms[$k] = $saved_term;
}
else {
$terms[$k] = new $term_class( $term );
}
}
//Utils::debug($terms);
}
else {
array_walk( $terms, create_function( '&$tag', '$tag = new ' . $term_class . '($tag);' ) );
}
return new Terms( $terms );
}
return new Terms();
}
/**
* Loads form values from an object
*
* @param string $key The name of a form component that will be loaded
* @return mixed The stored value returned
*/
function field_load($key)
{
return $this;
}
/**
* Stores a form value into the object
*
* @param string $key The name of a form component that will be stored
* @param mixed $value The value of the form component to store
*/
function field_save($key, $value)
{
Vocabulary::prep_update($value);
foreach($value as $term) {
if($term instanceof Term) {
$term->update();
}
}
}
/**
* Sort the term objects by mptt_left ASC to put them in tree order
*
* @return Terms A sorted Terms instance
*/
function tree_sort()
{
$terms = $this->getArrayCopy();
usort($terms, array($this, 'tree_sort_compare'));
return new Terms($terms);
}
/**
* Comparison function for tree_sort()
*
* @param Term $a A term to compare
* @param Term $b A term to compare
* @return bool the sorting result for the usort in tree_sort()
*/
function tree_sort_compare($a, $b)
{
return $a->mptt_left > $b->mptt_left;
}
}
?>