Merge branch 'xorg/master' into xorg/f/geocoding
authorStéphane Jacob <sj@m4x.org>
Wed, 18 May 2011 13:27:43 +0000 (15:27 +0200)
committerStéphane Jacob <sj@m4x.org>
Wed, 18 May 2011 13:27:43 +0000 (15:27 +0200)
1  2 
classes/direnum.php
classes/userfilter.php
classes/userfilter/conditions.inc.php
modules/payment/money/paypal.inc.php
modules/profile.php

diff --combined classes/direnum.php
@@@ -44,13 -44,11 +44,13 @@@ class DirEnu
      const ORIGINCORPS    = 'origincorps';
      const CORPSRANKS     = 'corpsranks';
  
 -    const NATIONALITIES  = 'nationalities';
 -    const COUNTRIES      = 'countries';
 -    const ADMINAREAS     = 'adminareas';
 -    const SUBADMINAREAS  = 'subadminareas';
 -    const LOCALITIES     = 'localities';
 +    const NATIONALITIES       = 'nationalities';
 +    const SUBLOCALITIES       = 'sublocalities';
 +    const LOCALITIES          = 'localities';
 +    const ADMNISTRATIVEAREAS3 = 'admnistrativeareas3';
 +    const ADMNISTRATIVEAREAS2 = 'admnistrativeareas2';
 +    const ADMNISTRATIVEAREAS1 = 'admnistrativeareas1';
 +    const COUNTRIES           = 'countries';
  
      const COMPANIES      = 'companies';
      const JOBDESCRIPTION = 'jobdescription';
@@@ -501,6 -499,7 +501,7 @@@ class DE_GroupesX extends DirEnumeratio
  // {{{ class DE_EducationSchools
  class DE_EducationSchools extends DirEnumeration
  {
+     protected $ac_beginwith = false;
      protected $idfield   = 'profile_education_enum.id';
      protected $valfield  = 'profile_education_enum.name';
      protected $valfield2 = 'profile_education_enum.abbreviation';
@@@ -592,49 -591,56 +593,49 @@@ class DE_Nationalities extends DirEnume
  }
  // }}}
  
 -// {{{ class DE_Countries
 -class DE_Countries extends DirEnumeration
 +// {{{ class DE_AddressesComponents
 +class DE_AddressesComponents extends DirEnumeration
  {
 -    protected $idfield   = 'geoloc_countries.iso_3166_1_a2';
 -    protected $valfield  = 'geoloc_countries.country';
 -    protected $valfield2 = 'geoloc_countries.countryEn';
 -    protected $from      = 'geoloc_countries';
 +    protected $idfield   = 'profile_addresses_components_enum.id';
 +    protected $valfield  = 'profile_addresses_components_enum.long_name';
 +    protected $from      = 'profile_addresses_components_enum';
  
 -    protected $ac_join   = 'INNER JOIN profile_addresses ON (geoloc_countries.iso_3166_1_a2 = profile_addresses.countryId)';
 -    protected $ac_unique = 'profile_addresses.pid';
 -    protected $ac_where  = 'profile_addresses.type = \'home\'';
 +    protected $ac_join   = 'INNER JOIN profile_addresses_components ON (profile_addresses_components.component_id = profile_addresses_components_enum.id)';
 +    protected $ac_unique = 'profile_addresses_components.pid';
 +    protected $ac_where  = 'profile_addresses_components.type = \'home\'';
  }
  // }}}
 -
 -// {{{ class DE_AdminAreas
 -class DE_AdminAreas extends DE_WithSuboption
 +// {{{ class DE_AddressesComponents extensions
 +class DE_Countries extends DE_AddressesComponents
  {
 -    protected $idfield   = 'geoloc_administrativeareas.id';
 -    protected $optfield  = 'geoloc_administrativeareas.country';
 -    protected $valfield  = 'geoloc_administrativeareas.name';
 -    protected $from      = 'geoloc_administrativeareas';
 +    protected $where = 'WHERE  FIND_IN_SET(\'country\', profile_addresses_components_enum.types)';
 +}
  
 -    protected $ac_join   = 'INNER JOIN profile_addresses ON (profile_addresses.administrativeAreaId = geoloc_administrativeareas.id)';
 -    protected $ac_unique = 'profile_addresses.pid';
 +class DE_Admnistrativeareas1 extends DE_AddressesComponents
 +{
 +    protected $where = 'WHERE  FIND_IN_SET(\'admnistrative_area_1\', profile_addresses_components_enum.types)';
  }
 -// }}}
  
 -// {{{ class DE_SubAdminAreas
 -class DE_SubAdminAreas extends DE_WithSuboption
 +class DE_Admnistrativeareas2 extends DE_AddressesComponents
  {
 -    protected $idfield   = 'geoloc_subadministrativeareas.id';
 -    protected $optfield  = 'geoloc_subadministrativeareas.administrativearea';
 -    protected $valfield  = 'geoloc_subadministrativeareas.name';
 -    protected $from      = 'geoloc_subadministrativeareas';
 +    protected $where = 'WHERE  FIND_IN_SET(\'admnistrative_area_2\', profile_addresses_components_enum.types)';
 +}
  
 -    protected $ac_join   = 'INNER JOIN profile_addresses ON (profile_addresses.subadministrativeAreaId = geoloc_subadministrativeareas.id)';
 -    protected $ac_unique = 'profile_addresses.pid';
 +class DE_Admnistrativeareas3 extends DE_AddressesComponents
 +{
 +    protected $where = 'WHERE  FIND_IN_SET(\'admnistrative_area_3\', profile_addresses_components_enum.types)';
  }
 -// }}}
  
 -// {{{ class DE_Localities
 -class DE_Localities extends DirEnumeration
 +class DE_Localities extends DE_AddressesComponents
  {
 -    protected $idfield   = 'geoloc_localities.id';
 -    protected $valfield  = 'geoloc_localities.name';
 -    protected $from      = 'geoloc_localities';
 +    protected $where = 'WHERE  FIND_IN_SET(\'locality\', profile_addresses_components_enum.types)';
 +}
  
 -    protected $ac_join   = 'INNER JOIN profile_addresses ON (profile_addresses.localityID = geoloc_localities.id)';
 -    protected $ac_unique = 'profile_addresses.pid';
 +class DE_Sublocalities extends DE_AddressesComponents
 +{
 +    protected $where = 'WHERE  FIND_IN_SET(\'sublocality\', profile_addresses_components_enum.types)';
  }
 +
  // }}}
  
  /** JOBS
diff --combined classes/userfilter.php
@@@ -846,6 -846,15 +846,15 @@@ class UserFilter extends PlFilte
          return $sub;
      }
  
+     private $gpfm = array();
+     public function addGroupFormerMemberFilter()
+     {
+         $this->requireAccounts();
+         $sub = '_' . $this->option++;
+         $this->gpfm[] = $sub;
+         return $sub;
+     }
      protected function groupJoins()
      {
          $joins = array();
                  $joins['gpm' . $sub] = PlSqlJoin::left('group_members', '$ME.uid = $UID AND $ME.asso_id = gpa' . $sub . '.id');
              }
          }
+         foreach ($this->gpfm as $sub) {
+             $joins['gpfm' . $sub] = PlSqlJoin::left('group_former_members', '$ME.uid = $UID');
+         }
          return $joins;
      }
  
  
      /** ADDRESSES
       */
 -    private $with_pa = false;
 -    public function addAddressFilter()
 +    private $types = array();
 +    public function addAddressFilter($type)
      {
          $this->requireProfiles();
          $this->with_pa = true;
 -        return 'pa';
 -    }
 -
 -    private $with_pac = false;
 -    public function addAddressCountryFilter()
 -    {
 -        $this->requireProfiles();
 -        $this->addAddressFilter();
 -        $this->with_pac = true;
 -        return 'gc';
 -    }
  
 -    private $with_pal = false;
 -    public function addAddressLocalityFilter()
 -    {
 -        $this->requireProfiles();
 -        $this->addAddressFilter();
 -        $this->with_pal = true;
 -        return 'gl';
 +        $sub = '_' . $this->option++;
 +        $this->types[$type] = $sub;
 +        return $sub;
      }
  
      protected function addressJoins()
      {
          $joins = array();
 -        if ($this->with_pa) {
 -            $joins['pa'] = PlSqlJoin::left('profile_addresses', '$ME.pid = $PID');
 -        }
 -        if ($this->with_pac) {
 -            $joins['gc'] = PlSqlJoin::left('geoloc_countries', '$ME.iso_3166_1_a2 = pa.countryID');
 -        }
 -        if ($this->with_pal) {
 -            $joins['gl'] = PlSqlJoin::left('geoloc_localities', '$ME.id = pa.localityID');
 +        foreach ($this->types as $type => $sub) {
 +            $joins['pa' . $sub] = PlSqlJoin::inner('profile_addresses', '$ME.pid = $PID');
 +            $joins['pac' . $sub] = PlSqlJoin::inner('profile_addresses_components',
 +                                                    '$ME.pid = pa' . $sub . '.pid AND $ME.jobid = pa' . $sub . '.jobid AND $ME.groupid = pa' . $sub . '.groupid AND $ME.type = pa' . $sub . '.type AND $ME.id = pa' . $sub . '.id');
 +            $joins['pace' . $sub] = PlSqlJoin::inner('profile_addresses_components_enum',
 +                                                     '$ME.id = pac' . $sub . '.component_id AND FIND_IN_SET({?}, $ME.types)', $type);
          }
 +
          return $joins;
      }
  
@@@ -912,6 -912,30 +912,30 @@@ class UFC_Group extends UserFilterCondi
      }
  }
  // }}}
+ // {{{ class UFC_GroupFormerMember
+ /** Filters users based on group former membership
+  * @param $group Group whose former members we are selecting
+  */
+ class UFC_GroupFormerMember extends UserFilterCondition
+ {
+     private $group;
+     public function __construct($group)
+     {
+         $this->group = $group;
+     }
+     public function buildCondition(PlFilter $uf)
+     {
+         // Groups are only visible for users with perm 'groups'.
+         if (!S::user()->checkPerms(User::PERM_GROUPS)) {
+             return self::COND_FALSE;
+         }
+         $sub = $uf->addGroupFormerMemberFilter();
+         return XDB::format('gpfm' . $sub . '.asso_id = {?}', $this->group);
+     }
+ }
+ // }}}
  // {{{ class UFC_Binet
  /** Selects users based on their belonging to a given (list of) binet
   * @param $binet either a binet_id or an array of binet_ids
@@@ -1006,20 -1030,17 +1030,20 @@@ class UFC_Email extends UserFilterCondi
  // {{{ class UFC_Address
  abstract class UFC_Address extends UserFilterCondition
  {
 -    /** Valid address type ('hq' is reserved for company addresses)
 +    /** Valid address type
       */
 -    const TYPE_HOME = 1;
 -    const TYPE_PRO  = 2;
 -    const TYPE_ANY  = 3;
 +    const TYPE_HOME     = 1;
 +    const TYPE_PRO      = 2;
 +    const TYPE_NON_HQ   = 3;
 +    const TYPE_HQ       = 4;
 +    const TYPE_ANY      = 7;
  
      /** Text for these types
       */
      protected static $typetexts = array(
          self::TYPE_HOME => 'home',
          self::TYPE_PRO  => 'pro',
 +        self::TYPE_HQ   => 'hq',
      );
  
      protected $type;
              }
          }
          if (count($types)) {
 -            $conds[] = XDB::format($sub . '.type IN {?}', $types);
 +            $conds[] = XDB::format('pa' . $sub . '.type IN {?}', $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)';
 +                    $conds[] = 'FIND_IN_SET(' . XDB::format('{?}', $text) . ', pa' . $sub . '.flags)';
                  }
              }
          }
  
  }
  // }}}
 -// {{{ 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, $uf->getVisibilityCondition($sub . '.pub'));
 -        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 $type Filter on address type
   * @param $flags Filter on address flags
   */
 -class UFC_AddressField extends UFC_Address
 +class UFC_AddressComponent extends UFC_Address
  {
 -    const FIELD_COUNTRY    = 1;
 -    const FIELD_ADMAREA    = 2;
 -    const FIELD_SUBADMAREA = 3;
 -    const FIELD_LOCALITY   = 4;
 -    const FIELD_ZIPCODE    = 5;
 +    static $components = array('sublocality', 'locality', 'administrative_area_level_3', 'administrative_area_level_2', 'administrative_area_level_1', 'country');
  
      /** Data of the filter
       */
      private $val;
      private $fieldtype;
 +    private $exact;
  
 -    public function __construct($val, $fieldtype, $type = null, $flags = self::FLAG_ANY)
 +    public function __construct($val, $fieldtype, $exact = true, $type = null, $flags = self::FLAG_ANY)
      {
 -        parent::__construct($type, $flags);
 +        if (!in_array($fieldtype, self::$components)) {
 +            Platal::page()->killError('Invalid address field type: ' . $this->fieldtype);
 +        }
  
 +        parent::__construct($type, $flags);
          if (!is_array($val)) {
              $val = array($val);
          }
          $this->val       = $val;
          $this->fieldtype = $fieldtype;
 +        $this->exact     = $exact;
      }
  
      public function buildCondition(PlFilter $uf)
      {
 -        $sub = $uf->addAddressFilter();
 -        $conds = $this->initConds($sub, $uf->getVisibilityCondition($sub . '.pub'));
 -
 -        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[] = XDB::format($sub . '.' . $field . ' IN {?}', $this->val);
 +        $sub = $uf->addAddressFilter($this->fieldtype);
 +        $conds = $this->initConds($sub, $uf->getVisibilityCondition('pa' . $sub . '.pub'));
 +        $conds[] = XDB::format('pace' . $sub . '.id IN {?}', $this->val);
  
          return implode(' AND ', $conds);
      }
@@@ -47,7 -47,7 +47,7 @@@ class PayPa
  
          $roboturl = str_replace("https://","http://",$globals->baseurl)
                    . '/' . $platal->ns . "payment/paypal_return/" . S::v('uid')
-                   . "?comment=" . urlencode(Env::v('comment'));
+                   . "?comment=" . urlencode(Env::v('comment')) . '?display=' . Post::i('display');
  
          $this->infos = array(
              'commercant' => array(
          );
  
          if ($user->hasProfile()) {
 -            $res = XDB::query("SELECT  pa.text, gl.name AS city, pa.postalCode AS zip, pa.countryId AS country,
 +            $res = XDB::query("SELECT  pa.text, pace2.short_name AS city, pace3.short_name AS zip, pace1.short_name AS country,
                                         IF(pp1.display_tel != '', pp1.display_tel, pp2.display_tel) AS night_phone_b
 -                                 FROM  profile_addresses AS pa
 -                            LEFT JOIN  profile_phones    AS pp1 ON (pp1.pid = pa.pid AND pp1.link_type = 'address'
 -                                                                    AND pp1.link_id = pa.id)
 -                            LEFT JOIN  profile_phones    AS pp2 ON (pp2.pid = pa.pid AND pp2.link_type = 'user'
 -                                                                    AND pp2.link_id = 0)
 -                            LEFT JOIN  geoloc_localities AS gl  ON (gl.id = pa.localityId)
 +                                 FROM  profile_addresses                 AS pa
 +                            LEFT JOIN  profile_phones                    AS pp1   ON (pp1.pid = pa.pid AND pp1.link_type = 'address' AND pp1.link_id = pa.id)
 +                            LEFT JOIN  profile_phones                    AS pp2   ON (pp2.pid = pa.pid AND pp2.link_type = 'user' AND pp2.link_id = 0)
 +                            LEFT JOIN  profile_addresses_components_enum AS pace1 ON (FIND_IN_SET('country', pace1.types))
 +                            LEFT JOIN  profile_addresses_components_enum AS pace2 ON (FIND_IN_SET('locality', pace2.types))
 +                            LEFT JOIN  profile_addresses_components_enum AS pace3 ON (FIND_IN_SET('postal_code', pace3.types))
 +                            LEFT JOIN  profile_addresses_components      AS pac1  ON (pa.pid = pac1.pid AND pa.jobid = pac1.jobid AND pa.groupid = pac1.groupid
 +                                                                                      AND pa.id = pac1.id AND pa.type = pac1.type AND pace1.id = pac1.component_id)
 +                            LEFT JOIN  profile_addresses_components      AS pac2  ON (pa.pid = pac2.pid AND pa.jobid = pac2.jobid AND pa.groupid = pac2.groupid
 +                                                                                      AND pa.id = pac2.id AND pa.type = pac2.type AND pace2.id = pac2.component_id)
 +                            LEFT JOIN  profile_addresses_components      AS pac3  ON (pa.pid = pac3.pid AND pa.jobid = pac3.jobid AND pa.groupid = pac3.groupid
 +                                                                                      AND pa.id = pac3.id AND pa.type = pac3.type AND pace3.id = pac3.component_id)
 +
                                  WHERE  pa.pid = {?} AND FIND_IN_SET('current', pa.flags)
 +                             GROUP BY  pa.pid, pa.jobid, pa.groupid, pa.id, pa.type
                                  LIMIT  1",
                                $user->profile()->id());
              $this->infos['client'] = array_map('replace_accent', array_merge($info_client, $res->fetchOneAssoc()));
diff --combined modules/profile.php
@@@ -33,7 -33,6 +33,7 @@@ class ProfileModule extends PLModul
              'profile/ax'                 => $this->make_hook('ax',                         AUTH_COOKIE, 'admin,edit_directory'),
              'profile/edit'               => $this->make_hook('p_edit',                     AUTH_MDP),
              'profile/ajax/address'       => $this->make_hook('ajax_address',               AUTH_COOKIE, 'user', NO_AUTH),
 +            'profile/ajax/address/del'   => $this->make_hook('ajax_address_del',           AUTH_MDP),
              'profile/ajax/tel'           => $this->make_hook('ajax_tel',                   AUTH_COOKIE, 'user', NO_AUTH),
              'profile/ajax/edu'           => $this->make_hook('ajax_edu',                   AUTH_COOKIE, 'user', NO_AUTH),
              'profile/ajax/medal'         => $this->make_hook('ajax_medal',                 AUTH_COOKIE, 'user', NO_AUTH),
          }
  
          // Build the page
-         $page->addJsLink('education.js', false); /* dynamic content */
-         $page->addJsLink('grades.js', false);    /* dynamic content */
+         $page->addJsLink('education.js', true, false); /* dynamic content */
+         $page->addJsLink('grades.js', true, false);    /* dynamic content */
          $page->addJsLink('profile.js');
          $wiz = new PlWizard('Profil', PlPage::getCoreTpl('plwizard.tpl'), true, true, false);
          $wiz->addUserData('profile', $profile);
          }
  
         $page->setTitle('Mon Profil');
 +       $page->assign('hrpid', $profile->hrid());
         if (isset($success) && $success) {
             $page->trigSuccess('Ton profil a bien été mis à jour.');
         }
          $page->assign('address', array());
      }
  
 +    function handler_ajax_address_del($page, $hrpid)
 +    {
 +        if ($profile = Profile::get($hrpid)) {
 +            if (S::user()->canEdit($profile)) {
 +                $address = Post::t('address');
 +                if (is_null(AddressReq::get_request($profile->id(), 0, 0, Address::LINK_PROFILE, $address))) {
 +                    $req = new AddressReq(S::user(), $profile, $address, $profile->id(), 0, 0, Address::LINK_PROFILE);
 +                    $req->submit();
 +                }
 +            }
 +        }
 +        exit();
 +    }
 +
      function handler_ajax_tel($page, $prefid, $prefname, $telid, $subField, $mainField, $mainId)
      {
          pl_content_headers("text/html");