+// }}}
+
+// {{{ class UFC_Address
+abstract class UFC_Address implements UserFilterCondition
+{
+ /** Valid address type ('hq' is reserved for company addresses)
+ */
+ const TYPE_HOME = 1;
+ const TYPE_PRO = 2;
+ const TYPE_ANY = 3;
+
+ /** Text for these types
+ */
+ protected static $typetexts = array(
+ self::TYPE_HOME => 'home',
+ self::TYPE_PRO => 'pro',
+ );
+
+ protected $type;
+
+ /** Flags for addresses
+ */
+ const FLAG_CURRENT = 0x0001;
+ const FLAG_TEMP = 0x0002;
+ const FLAG_SECOND = 0x0004;
+ const FLAG_MAIL = 0x0008;
+ const FLAG_CEDEX = 0x0010;
+
+ // Binary OR of those flags
+ const FLAG_ANY = 0x001F;
+
+ /** Text of these flags
+ */
+ protected static $flagtexts = array(
+ self::FLAG_CURRENT => 'current',
+ self::FLAG_TEMP => 'temporary',
+ self::FLAG_SECOND => 'secondary',
+ self::FLAG_MAIL => 'mail',
+ self::FLAG_CEDEX => 'cedex',
+ );
+
+ protected $flags;
+
+ public function __construct($type = null, $flags = null)
+ {
+ $this->type = $type;
+ $this->flags = $flags;
+ }
+
+ protected function initConds($sub)
+ {
+ $conds = array();
+ $types = array();
+ foreach (self::$typetexts as $flag => $type) {
+ if ($flag & $this->type) {
+ $types[] = $type;
+ }
+ }
+ if (count($types)) {
+ $conds[] = $sub . '.type IN ' . XDB::formatArray($types);
+ }
+
+ if ($this->flags != self::FLAG_ANY) {
+ foreach(self::$flagtexts as $flag => $text) {
+ if ($flag & $this->flags) {
+ $conds[] = 'FIND_IN_SET(' . XDB::format('{?}', $text) . ', ' . $sub . '.flags)';
+ }
+ }
+ }
+ return $conds;
+ }
+
+}
+// }}}
+
+// {{{ class UFC_AddressText
+/** Select users based on their address, using full text search
+ * @param $text Text for filter in fulltext search
+ * @param $textSearchMode Mode for search (one of XDB::WILDCARD_*)
+ * @param $type Filter on address type
+ * @param $flags Filter on address flags
+ * @param $country Filter on address country
+ * @param $locality Filter on address locality
+ */
+class UFC_AddressText extends UFC_Address
+{
+
+ private $text;
+ private $textSearchMode;
+
+ public function __construct($text = null, $textSearchMode = XDB::WILDCARD_CONTAINS,
+ $type = null, $flags = self::FLAG_ANY, $country = null, $locality = null)
+ {
+ parent::__construct($type, $flags);
+ $this->text = $text;
+ $this->textSearchMode = $textSearchMode;
+ $this->country = $country;
+ $this->locality = $locality;
+ }
+
+ private function mkMatch($txt)
+ {
+ return XDB::formatWildcards($this->textSearchMode, $txt);
+ }
+
+ public function buildCondition(PlFilter &$uf)
+ {
+ $sub = $uf->addAddressFilter();
+ $conds = $this->initConds($sub);
+ if ($this->text != null) {
+ $conds[] = $sub . '.text' . $this->mkMatch($this->text);
+ }
+
+ if ($this->country != null) {
+ $subc = $uf->addAddressCountryFilter();
+ $subconds = array();
+ $subconds[] = $subc . '.country' . $this->mkMatch($this->country);
+ $subconds[] = $subc . '.countryFR' . $this->mkMatch($this->country);
+ $conds[] = implode(' OR ', $subconds);
+ }
+
+ if ($this->locality != null) {
+ $subl = $uf->addAddressLocalityFilter();
+ $conds[] = $subl . '.name' . $this->mkMatch($this->locality);
+ }
+
+ return implode(' AND ', $conds);
+ }
+}
+// }}}
+
+// {{{ class UFC_AddressField
+/** Filters users based on their address,
+ * @param $val Either a code for one of the fields, or an array of such codes
+ * @param $fieldtype The type of field to look for
+ * @param $type Filter on address type
+ * @param $flags Filter on address flags
+ */
+class UFC_AddressField extends UFC_Address
+{
+ const FIELD_COUNTRY = 1;
+ const FIELD_ADMAREA = 2;
+ const FIELD_SUBADMAREA = 3;
+ const FIELD_LOCALITY = 4;
+ const FIELD_ZIPCODE = 5;
+
+ /** Data of the filter
+ */
+ private $val;
+ private $fieldtype;
+
+ public function __construct($val, $fieldtype, $type = null, $flags = self::FLAG_ANY)
+ {
+ parent::__construct($type, $flags);
+
+ if (!is_array($val)) {
+ $val = array($val);
+ }
+ $this->val = $val;
+ $this->fieldtype = $fieldtype;
+ }
+
+ public function buildCondition(PlFilter &$uf)
+ {
+ $sub = $uf->addAddressFilter();
+ $conds = $this->initConds($sub);
+
+ switch ($this->fieldtype) {
+ case self::FIELD_COUNTRY:
+ $field = 'countryId';
+ break;
+ case self::FIELD_ADMAREA:
+ $field = 'administrativeAreaId';
+ break;
+ case self::FIELD_SUBADMAREA:
+ $field = 'subAdministrativeAreaId';
+ break;
+ case self::FIELD_LOCALITY:
+ $field = 'localityId';
+ break;
+ case self::FIELD_ZIPCODE:
+ $field = 'postalCode';
+ break;
+ default:
+ Platal::page()->killError('Invalid address field type: ' . $this->fieldtype);
+ }
+ $conds[] = $sub . '.' . $field . ' IN ' . XDB::formatArray($this->val);
+
+ return implode(' AND ', $conds);
+ }
+}
+// }}}
+
+// {{{ class UFC_Corps
+/** Filters users based on the corps they belong to
+ * @param $corps Corps we are looking for (abbreviation)
+ * @param $type Whether we search for original or current corps
+ */
+class UFC_Corps implements UserFilterCondition
+{
+ const CURRENT = 1;
+ const ORIGIN = 2;
+
+ private $corps;
+ private $type;
+
+ public function __construct($corps, $type = self::CURRENT)
+ {
+ $this->corps = $corps;
+ $this->type = $type;
+ }
+
+ public function buildCondition(PlFilter &$uf)
+ {
+ /** Tables shortcuts:
+ * pc for profile_corps,
+ * pceo for profile_corps_enum - orginal
+ * pcec for profile_corps_enum - current
+ */
+ $sub = $uf->addCorpsFilter($this->type);
+ $cond = $sub . '.abbreviation = ' . $corps;
+ return $cond;
+ }
+}
+// }}}
+
+// {{{ class UFC_Corps_Rank
+/** Filters users based on their rank in the corps
+ * @param $rank Rank we are looking for (abbreviation)
+ */
+class UFC_Corps_Rank implements UserFilterCondition
+{
+ private $rank;
+ public function __construct($rank)
+ {
+ $this->rank = $rank;
+ }
+
+ public function buildCondition(PlFilter &$uf)
+ {
+ /** Tables shortcuts:
+ * pcr for profile_corps_rank
+ */
+ $sub = $uf->addCorpsRankFilter();
+ $cond = $sub . '.abbreviation = ' . $rank;
+ return $cond;
+ }
+}
+// }}}
+
+// {{{ class UFC_Job_Company
+/** Filters users based on the company they belong to
+ * @param $type The field being searched (self::JOBID, self::JOBNAME or self::JOBACRONYM)
+ * @param $value The searched value
+ */
+class UFC_Job_Company implements UserFilterCondition
+{
+ const JOBID = 'id';
+ const JOBNAME = 'name';
+ const JOBACRONYM = 'acronym';
+
+ private $type;
+ private $value;
+
+ public function __construct($type, $value)
+ {
+ $this->assertType($type);
+ $this->type = $type;
+ $this->value = $value;
+ }
+
+ private function assertType($type)
+ {
+ if ($type != self::JOBID && $type != self::JOBNAME && $type != self::JOBACRONYM) {
+ Platal::page()->killError("Type de recherche non valide.");
+ }
+ }
+
+ public function buildCondition(PlFilter &$uf)
+ {
+ $sub = $uf->addJobCompanyFilter();
+ $cond = $sub . '.' . $this->type . ' = ' . XDB::format('{?}', $this->value);
+ return $cond;
+ }
+}
+// }}}