+
+ public static function comparisonFromXDBWildcard($wildcard)
+ {
+ switch ($wildcard) {
+ case XDB::WILDCARD_EXACT:
+ return self::OP_EQUALS;
+ case XDB::WILDCARD_PREFIX:
+ return self::OP_PREFIX;
+ case XDB::WILDCARD_SUFFIX:
+ return self::OP_SUFFIX;
+ case XDB::WILDCARD_CONTAINS:
+ return self::OP_CONTAINS;
+ }
+ throw new Exception("Unknown wildcard mode: $wildcard");
+ }
+
+ public static function xdbWildcardFromComparison($comparison)
+ {
+ if (!self::isStringComparison($comparison)) {
+ throw new Exception("Unknown string coparison: $comparison");
+ }
+ switch ($comparison) {
+ case self::OP_EQUALS:
+ return XDB::WILDCARD_EXACT;
+ case self::OP_PREFIX:
+ return XDB::WILDCARD_PREFIX;
+ case self::OP_SUFFIX:
+ return XDB::WILDCARD_SUFFIX;
+ case self::OP_CONTAINS:
+ return XDB::WILDCARD_CONTAINS;
+ }
+ }
+
+ private static function isNumericComparison($comparison)
+ {
+ return $comparison == self::OP_EQUALS
+ || $comparison == self::OP_GREATER
+ || $comparison == self::OP_NOTGREATER
+ || $comparison == self::OP_LESSER
+ || $comparison == self::OP_NOTLESSER;
+ }
+
+ private static function isStringComparison($comparison)
+ {
+ return $comparison == self::OP_EQUALS
+ || $comparison == self::OP_CONTAINS
+ || $comparison == self::OP_PREFIX
+ || $comparison == self::OP_SUFFIX;
+ }
+
+ public static function fromExport(array $export)
+ {
+ $export = new PlDict($export);
+ if (!$export->has('type')) {
+ throw new Exception("Missing type in export");
+ }
+ $type = $export->s('type');
+ $cond = null;
+ switch ($type) {
+ case 'and':
+ case 'or':
+ case 'not':
+ case 'true':
+ case 'false':
+ $class = 'pfc_' . $type;
+ $cond = new $class();
+ break;
+
+ case 'host':
+ if ($export->has('ip')) {
+ $cond = new UFC_Ip($export->s('ip'));
+ }
+ break;
+
+ case 'comment':
+ if ($export->has('text') && $export->s('comparison') == self::OP_CONTAINS) {
+ $cond = new UFC_Comment($export->s('text'));
+ }
+ break;
+
+ case 'promo':
+ if ($export->has('promo') && self::isNumericComparison($export->s('comparison'))) {
+ $cond = new UFC_Promo($export->s('comparison'),
+ $export->s('grade', UserFilter::DISPLAY),
+ $export->s('promo'));
+ }
+ break;
+
+ case 'lastname':
+ case 'name':
+ case 'firstname':
+ case 'nickname':
+ case 'pseudonym':
+ if ($export->has('text')) {
+ $flag = self::xdbWildcardFromComparison($export->s('comparison'));
+ if ($export->b('search_in_variants')) {
+ $flag |= UFC_Name::VARIANTS;
+ }
+ if ($export->b('search_in_particle')) {
+ $flag |= UFC_Name::PARTICLE;
+ }
+ $cond = new UFC_Name($type, $export->s('text'), $flag);
+ }
+ break;
+
+ case 'account_type':
+ case 'account_perm':
+ case 'hrpid':
+ case 'hruid':
+ $values = $export->v('values', array());
+ $class = 'ufc_' . str_replace('_', '', $type);
+ $cond = new $class($values);
+ break;
+
+ case 'school_id':
+ $values = $export->v('values', array());
+ $school_type = $export->s('school_type');
+ $cond = new UFC_SchoolId($school_type, $values);
+ break;
+
+ case 'has_profile':
+ case 'has_email_redirect':
+ case 'has_valid_email':
+ $class = 'ufc_' . str_replace('_', '', $type);
+ $cond = new $class();
+ break;
+
+ default:
+ throw new Exception("Unknown condition type: $type");
+ }
+ if (is_null($cond)) {
+ throw new Exception("Unsupported $type definition");
+ }
+ if ($cond instanceof PFC_NChildren) {
+ $children = $export->v('children', array());
+ foreach ($children as $child) {
+ $cond->addChild(self::fromExport($child));
+ }
+ } else if ($cond instanceof PFC_OneChild) {
+ if ($export->has('child')) {
+ $cond->setChild(self::fromExport($export->v('child')));
+ }
+ }
+ return $cond;
+ }