+__autoload('xdb');
+
+// {{{ class PlLimit
+class PlLimit
+{
+ private $count = null;
+ private $from = null;
+
+ public function __construct($count = null, $from = null)
+ {
+ $this->count = $count;
+ $this->from = $from;
+ }
+
+ public function getSql()
+ {
+ if (!is_null($this->count) && $this->count != 0) {
+ if (!is_null($this->from) && $this->from != 0) {
+ return XDB::format('LIMIT {?}, {?}', (int)$this->from, (int)$this->count);
+ } else {
+ return XDB::format('LIMIT {?}', (int)$this->count);
+ }
+ }
+ return '';
+ }
+}
+// }}}
+
+// {{{ class PlFilterOrder
+/** Base class for ordering results of a query.
+ * Parameters for the ordering must be given to the constructor ($desc for a
+ * descending order).
+ * The getSortTokens function is used to get actual ordering part of the query.
+ */
+abstract class PlFilterOrder implements PlExportable
+{
+ protected $desc = false;
+ public function __construct($desc = false)
+ {
+ $this->desc = $desc;
+ $this->_tokens = null;
+ }
+
+ protected function buildExport($type)
+ {
+ $export = array('type' => $type);
+ if ($this->desc) {
+ $export['order'] = 'desc';
+ }
+ return $export;
+ }
+
+ public function export()
+ {
+ throw new Exception("This instance is not exportable");
+ }
+
+ public function toggleDesc()
+ {
+ $this->desc = !$this->desc;
+ }
+
+ public function setDescending($desc = true)
+ {
+ $this->desc = $desc;
+ }
+
+ public function buildSort(PlFilter $pf)
+ {
+ $sel = $this->getSortTokens($pf);
+ $this->_tokens = $sel;
+ if (!is_array($sel)) {
+ $sel = array($sel);
+ }
+ if ($this->desc) {
+ foreach ($sel as $k => $s) {
+ $sel[$k] = $s . ' DESC';
+ }
+ }
+ return $sel;
+ }
+
+ /** This function must return the tokens to use for ordering
+ * @param $pf The PlFilter whose results must be ordered
+ * @return The name of the field to use for ordering results
+ */
+ abstract protected function getSortTokens(PlFilter $pf);
+}
+// }}}
+
+// {{{ class PlFilterGroupableOrder
+/** Extension of a PlFilterOrder, for orders where the value on which ordering
+ * is done could be used for grouping results (promo, country, ...)
+ */
+abstract class PlFilterGroupableOrder extends PlFilterOrder
+{
+ /** This function will be called when trying to retrieve groups;
+ * the returned token will be used to group the values.
+ * It will always be called AFTER getSortTokens().
+ */
+ public function getGroupToken(PlFilter $pf)
+ {
+ return $this->_tokens;
+ }
+
+ /** This function is called when trying to restrict to one of the
+ * specific values of the group token.
+ *
+ * @return A PlFilterCondition.
+ */
+ public function getCondition($group_value)
+ {
+ return null;
+ }
+}
+// }}}
+
+// {{{ class PFO_Random
+class PFO_Random extends PlFilterOrder
+{
+ private $seed = null;
+
+ public function __construct($seed = null, $desc = false)
+ {
+ parent::__construct($desc);
+ $this->seed = $seed;
+ }
+
+ protected function getSortTokens(PlFilter $pf)
+ {
+ if ($this->seed == null) {
+ return 'RAND()';
+ } else {
+ return XDB::format('RAND({?})', $this->seed);
+ }
+ }
+
+ public function export()
+ {
+ $export = array('type' => 'random',);
+ if ($this->seed !== null)
+ $export['seed'] = $this->seed;
+ return $export;
+ }
+}
+// }}}
+
+// {{{ interface PlFilterCondition
+interface PlFilterCondition extends PlExportable
+{
+ const COND_TRUE = 'TRUE';
+ const COND_FALSE = 'FALSE';
+
+ public function buildCondition(PlFilter $pf);
+}
+// }}}
+
+// {{{ class PFC_OneChild
+abstract class PFC_OneChild implements PlFilterCondition