File indexing completed on 2024-12-22 05:37:04

0001 <?php
0002 
0003 /**
0004  * Copyright (c) 2007-2011, Servigistics, Inc.
0005  * All rights reserved.
0006  *
0007  * Redistribution and use in source and binary forms, with or without
0008  * modification, are permitted provided that the following conditions are met:
0009  *
0010  *  - Redistributions of source code must retain the above copyright notice,
0011  *    this list of conditions and the following disclaimer.
0012  *  - Redistributions in binary form must reproduce the above copyright
0013  *    notice, this list of conditions and the following disclaimer in the
0014  *    documentation and/or other materials provided with the distribution.
0015  *  - Neither the name of Servigistics, Inc. nor the names of
0016  *    its contributors may be used to endorse or promote products derived from
0017  *    this software without specific prior written permission.
0018  *
0019  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0020  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0021  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0022  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0023  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0024  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0025  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0026  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0027  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0028  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0029  * POSSIBILITY OF SUCH DAMAGE.
0030  *
0031  * @copyright Copyright 2007-2011 Servigistics, Inc. (http://servigistics.com)
0032  * @license http://solr-php-client.googlecode.com/svn/trunk/COPYING New BSD
0033  * @version $Id: Document.php 54 2011-02-04 16:29:18Z donovan.jimenez $
0034  *
0035  * @package Apache
0036  * @subpackage Solr
0037  * @author Donovan Jimenez <djimenez@conduit-it.com>
0038  */
0039 
0040 /**
0041  * Holds Key / Value pairs that represent a Solr Document along with any associated boost
0042  * values. Field values can be accessed by direct dereferencing such as:
0043  * <code>
0044  * ...
0045  * $document->title = 'Something';
0046  * echo $document->title;
0047  * ...
0048  * </code>
0049  *
0050  * Additionally, the field values can be iterated with foreach
0051  *
0052  * <code>
0053  * foreach ($document as $fieldName => $fieldValue)
0054  * {
0055  * ...
0056  * }
0057  * </code>
0058  */
0059 class Zend_Service_Solr_Document implements IteratorAggregate {
0060     /**
0061      * SVN Revision meta data for this class
0062      */
0063     const SVN_REVISION = '$Revision: 54 $';
0064 
0065     /**
0066      * SVN ID meta data for this class
0067      */
0068     const SVN_ID = '$Id: Document.php 54 2011-02-04 16:29:18Z donovan.jimenez $';
0069 
0070     /**
0071      * Document boost value
0072      *
0073      * @var float
0074      */
0075     protected $_documentBoost = false;
0076 
0077     /**
0078      * Document field values, indexed by name
0079      *
0080      * @var array
0081      */
0082     protected $_fields = array();
0083 
0084     /**
0085      * Document field boost values, indexed by name
0086      *
0087      * @var array array of floats
0088      */
0089     protected $_fieldBoosts = array();
0090 
0091     /**
0092      * Clear all boosts and fields from this document
0093      */
0094     public function clear() {
0095         $this->_documentBoost = false;
0096 
0097         $this->_fields = array();
0098         $this->_fieldBoosts = array();
0099     }
0100 
0101     /**
0102      * Get current document boost
0103      *
0104      * @return mixed will be false for default, or else a float
0105      */
0106     public function getBoost() {
0107         return $this->_documentBoost;
0108     }
0109 
0110     /**
0111      * Set document boost factor
0112      *
0113      * @param mixed $boost Use false for default boost, else cast to float that should be > 0 or will be treated as false
0114      */
0115     public function setBoost($boost) {
0116         $boost = (float) $boost;
0117 
0118         if ($boost > 0.0) {
0119             $this->_documentBoost = $boost;
0120         } else {
0121             $this->_documentBoost = false;
0122         }
0123     }
0124 
0125     /**
0126      * Add a value to a multi-valued field
0127      *
0128      * NOTE: the solr XML format allows you to specify boosts
0129      * PER value even though the underlying Lucene implementation
0130      * only allows a boost per field. To remedy this, the final
0131      * field boost value will be the product of all specified boosts
0132      * on field values - this is similar to SolrJ's functionality.
0133      *
0134      * <code>
0135      * $doc = new Zend_Service_Solr_Document();
0136      *
0137      * $doc->addField('foo', 'bar', 2.0);
0138      * $doc->addField('foo', 'baz', 3.0);
0139      *
0140      * // resultant field boost will be 6!
0141      * echo $doc->getFieldBoost('foo');
0142      * </code>
0143      *
0144      * @param string $key
0145      * @param mixed $value
0146      * @param mixed $boost Use false for default boost, else cast to float that should be > 0 or will be treated as false
0147      */
0148     public function addField($key, $value, $boost = false) {
0149         if (!isset($this->_fields[$key])) {
0150             // create holding array if this is the first value
0151             $this->_fields[$key] = array();
0152         } else if (!is_array($this->_fields[$key])) {
0153             // move existing value into array if it is not already an array
0154             $this->_fields[$key] = array($this->_fields[$key]);
0155         }
0156 
0157         if ($this->getFieldBoost($key) === false) {
0158             // boost not already set, set it now
0159             $this->setFieldBoost($key, $boost);
0160         } else if ((float) $boost > 0.0) {
0161             // multiply passed boost with current field boost - similar to SolrJ implementation
0162             $this->_fieldBoosts[$key] *= (float) $boost;
0163         }
0164 
0165         // add value to array
0166         $this->_fields[$key][] = $value;
0167     }
0168 
0169     /**
0170      * Handle the array manipulation for a multi-valued field
0171      *
0172      * @param string $key
0173      * @param string $value
0174      * @param mixed $boost Use false for default boost, else cast to float that should be > 0 or will be treated as false
0175      *
0176      * @deprecated Use addField(...) instead
0177      */
0178     public function setMultiValue($key, $value, $boost = false) {
0179         $this->addField($key, $value, $boost);
0180     }
0181 
0182     /**
0183      * Get field information
0184      *
0185      * @param string $key
0186      * @return mixed associative array of info if field exists, false otherwise
0187      */
0188     public function getField($key) {
0189         if (isset($this->_fields[$key])) {
0190             return array(
0191                 'name' => $key,
0192                 'value' => $this->_fields[$key],
0193                 'boost' => $this->getFieldBoost($key)
0194             );
0195         }
0196 
0197         return false;
0198     }
0199 
0200     /**
0201      * Set a field value. Multi-valued fields should be set as arrays
0202      * or instead use the addField(...) function which will automatically
0203      * make sure the field is an array.
0204      *
0205      * @param string $key
0206      * @param mixed $value
0207      * @param mixed $boost Use false for default boost, else cast to float that should be > 0 or will be treated as false
0208      */
0209     public function setField($key, $value, $boost = false) {
0210         $this->_fields[$key] = $value;
0211         $this->setFieldBoost($key, $boost);
0212     }
0213 
0214     /**
0215      * Get the currently set field boost for a document field
0216      *
0217      * @param string $key
0218      * @return float currently set field boost, false if one is not set
0219      */
0220     public function getFieldBoost($key) {
0221         return isset($this->_fieldBoosts[$key]) ? $this->_fieldBoosts[$key] : false;
0222     }
0223 
0224     /**
0225      * Set the field boost for a document field
0226      *
0227      * @param string $key field name for the boost
0228      * @param mixed $boost Use false for default boost, else cast to float that should be > 0 or will be treated as false
0229      */
0230     public function setFieldBoost($key, $boost) {
0231         $boost = (float) $boost;
0232 
0233         if ($boost > 0.0) {
0234             $this->_fieldBoosts[$key] = $boost;
0235         } else {
0236             $this->_fieldBoosts[$key] = false;
0237         }
0238     }
0239 
0240     /**
0241      * Return current field boosts, indexed by field name
0242      *
0243      * @return array
0244      */
0245     public function getFieldBoosts() {
0246         return $this->_fieldBoosts;
0247     }
0248 
0249     /**
0250      * Get the names of all fields in this document
0251      *
0252      * @return array
0253      */
0254     public function getFieldNames() {
0255         return array_keys($this->_fields);
0256     }
0257 
0258     /**
0259      * Get the values of all fields in this document
0260      *
0261      * @return array
0262      */
0263     public function getFieldValues() {
0264         return array_values($this->_fields);
0265     }
0266 
0267     /**
0268      * IteratorAggregate implementation function. Allows usage:
0269      *
0270      * <code>
0271      * foreach ($document as $key => $value)
0272      * {
0273      *  ...
0274      * }
0275      * </code>
0276      */
0277     public function getIterator() {
0278         $arrayObject = new ArrayObject($this->_fields);
0279 
0280         return $arrayObject->getIterator();
0281     }
0282 
0283     /**
0284      * Magic get for field values
0285      *
0286      * @param string $key
0287      * @return mixed
0288      */
0289     public function __get($key) {
0290         if (isset($this->_fields[$key])) {
0291             return $this->_fields[$key];
0292         }
0293 
0294         return null;
0295     }
0296 
0297     /**
0298      * Magic set for field values. Multi-valued fields should be set as arrays
0299      * or instead use the addField(...) function which will automatically
0300      * make sure the field is an array.
0301      *
0302      * @param string $key
0303      * @param mixed $value
0304      */
0305     public function __set($key, $value) {
0306         $this->setField($key, $value);
0307     }
0308 
0309     /**
0310      * Magic isset for fields values.  Do not call directly. Allows usage:
0311      *
0312      * <code>
0313      * isset($document->some_field);
0314      * </code>
0315      *
0316      * @param string $key
0317      * @return boolean
0318      */
0319     public function __isset($key) {
0320         return isset($this->_fields[$key]);
0321     }
0322 
0323     /**
0324      * Magic unset for field values. Do not call directly. Allows usage:
0325      *
0326      * <code>
0327      * unset($document->some_field);
0328      * </code>
0329      *
0330      * @param string $key
0331      */
0332     public function __unset($key) {
0333         unset($this->_fields[$key]);
0334         unset($this->_fieldBoosts[$key]);
0335     }
0336 
0337 }