Enable a DeltaTen module and profile page.
authorRaphaël Barrois <raphael.barrois@polytechnique.org>
Mon, 28 Feb 2011 21:05:51 +0000 (22:05 +0100)
committerRaphaël Barrois <raphael.barrois@polytechnique.org>
Sun, 8 May 2011 23:28:54 +0000 (01:28 +0200)
Signed-off-by: Raphaël Barrois <raphael.barrois@polytechnique.org>
classes/profile.php
classes/xorg.php
configs/platal.ini
modules/deltaten.php [new file with mode: 0644]
modules/profile.php
modules/profile/deltaten.inc.php [new file with mode: 0644]
modules/profile/page.inc.php
templates/deltaten/index.tpl [new file with mode: 0644]
templates/profile/deltaten.tpl [new file with mode: 0644]
templates/skin/common.menu.tpl
upgrade/1.1.0/10_deltaten.sql [new file with mode: 0644]

index e63bfe5..177155a 100644 (file)
@@ -109,10 +109,11 @@ class Profile implements PlExportable
     const FETCH_PHONES         = 0x000100;
     const FETCH_JOB_TERMS      = 0x000200;
     const FETCH_MENTOR_TERMS   = 0x000400;
+    const FETCH_DELTATEN       = 0x000800;
 
     const FETCH_MINIFICHES   = 0x00012D; // FETCH_ADDRESSES | FETCH_EDU | FETCH_JOBS | FETCH_NETWORKING | FETCH_PHONES
 
-    const FETCH_ALL          = 0x0007FF; // OR of FETCH_*
+    const FETCH_ALL          = 0x000FFF; // OR of FETCH_*
 
     static public $descriptions = array(
         'search_names'    => 'Noms',
@@ -144,7 +145,8 @@ class Profile implements PlExportable
         'langues'         => 'Langues',
         'expertise'       => 'Expertises (mentoring)',
         'terms'           => 'Compétences (mentoring)',
-        'countries'       => 'Pays (mentoring)'
+        'countries'       => 'Pays (mentoring)',
+        'deltaten'        => 'Opération N N-10',
     );
 
     private $fetched_fields  = 0x000000;
@@ -421,8 +423,8 @@ class Profile implements PlExportable
 
     /**
      * Clears a profile.
-     *  *always deletes in: profile_addresses, profile_binets, profile_job,
-     *      profile_langskills, profile_mentor, profile_networking,
+     *  *always deletes in: profile_addresses, profile_binets, profile_deltaten,
+     *      profile_job, profile_langskills, profile_mentor, profile_networking,
      *      profile_phones, profile_skills, watch_profile
      *  *always keeps in: profile_corps, profile_display, profile_education,
      *      profile_medals, profile_name, profile_photos, search_name
@@ -433,7 +435,8 @@ class Profile implements PlExportable
         $tables = array(
             'profile_job', 'profile_langskills', 'profile_mentor',
             'profile_networking', 'profile_skills', 'watch_profile',
-            'profile_phones', 'profile_addresses', 'profile_binets');
+            'profile_phones', 'profile_addresses', 'profile_binets',
+            'profile_deltaten');
 
         foreach ($tables as $t) {
             XDB::execute('DELETE FROM  ' . $t . '
@@ -804,6 +807,44 @@ class Profile implements PlExportable
         }
     }
 
+    /** DeltaTen
+     */
+
+    /** Find out whether this profile may take part to the "DeltaTen" operation.
+     * @param $role Which role to select ('young' or 'old')
+     * @return Boolean: whether it is enabled.
+     */
+    const DELTATEN_YOUNG = 'young';
+    const DELTATEN_OLD = 'old';
+    public function isDeltaTenEnabled($role)
+    {
+        global $globals;
+        switch ($role) {
+        case self::DELTATEN_YOUNG:
+            return ($this->mainGrade() == UserFilter::GRADE_ING && $this->yearpromo() >= $globals->deltaten->first_promo_young);
+        case self::DELTATEN_OLD:
+            // Roughly compute the current promo in second year on the campus:
+            // Promo 2010 is in second year between 09/2011 and 08/2012 => use 2012.
+            // DeltaTen program begins around January of the second year.
+            $promo_on_platal = ((int) date('Y')) - 2;
+            return ($this->mainGrade() == UserFilter::GRADE_ING && $this->yearpromo() >= $globals->deltaten->first_promo_young - 10 && $this->yearpromo() <= $promo_on_platal - 10);
+        default:
+            Platal::assert(false, "Invalid DeltaTen role $role");
+        }
+    }
+
+    /** Retrieve the "Deltaten" message of the user.
+     * Returns "null" if the message is empty or the user is not taking part to the
+     * DeltaTen operation.
+     */
+    public function getDeltatenMessage()
+    {
+        if ($this->isDeltaTenEnabled(self::DELTATEN_OLD)) {
+            return $this->deltaten_message;
+        } else {
+            return null;
+        }
+    }
 
     /* Binets
      */
@@ -907,16 +948,17 @@ class Profile implements PlExportable
                                      pe.entry_year, pe.grad_year, pe.promo_year, pe.program, pe.fieldid,
                                      IF ({?}, pse.text, NULL) AS section,
                                      pn_f.name AS firstname, pn_l.name AS lastname,
-                                     IF{?}, pn_n.name, NULL) AS nickname,
-                                     IF(pn_uf.name IS NULL, pn_f.name, pn_uf.name) AS firstname_ordinary,
-                                     IF(pn_ul.name IS NULL, pn_l.name, pn_ul.name) AS lastname_ordinary,
+                                     IF ({?}, pn_n.name, NULL) AS nickname,
+                                     IF (pn_uf.name IS NULL, pn_f.name, pn_uf.name) AS firstname_ordinary,
+                                     IF (pn_ul.name IS NULL, pn_l.name, pn_ul.name) AS lastname_ordinary,
                                      pd.yourself, pd.promo, pd.short_name, pd.public_name AS full_name,
                                      pd.directory_name, pd.public_name, pd.private_name,
-                                     IF(pp.pub IN {?}, pp.display_tel, NULL) AS mobile,
+                                     IF (pp.pub IN {?}, pp.display_tel, NULL) AS mobile,
                                      (ph.pub IN {?} AND ph.attach IS NOT NULL) AS has_photo,
                                      ph.x AS photo_width, ph.y AS photo_height,
                                      p.last_change < DATE_SUB(NOW(), INTERVAL 365 DAY) AS is_old,
                                      pm.expertise AS mentor_expertise,
+                                     IF ({?}, pdt.message, NULL) AS deltaten_message,
                                      ap.uid AS owner_id
                                FROM  profiles AS p
                          INNER JOIN  profile_display AS pd ON (pd.pid = p.pid)
@@ -935,6 +977,7 @@ class Profile implements PlExportable
                           LEFT JOIN  profile_phones AS pp ON (pp.pid = p.pid AND pp.link_type = \'user\' AND tel_type = \'mobile\')
                           LEFT JOIN  profile_photos AS ph ON (ph.pid = p.pid)
                           LEFT JOIN  profile_mentor AS pm ON (pm.pid = p.pid)
+                          LEFT JOIN  profile_deltaten AS pdt ON (pdt.pid = p.pid)
                           LEFT JOIN  account_profiles AS ap ON (ap.pid = p.pid AND FIND_IN_SET(\'owner\', ap.perms))
                               WHERE  p.pid IN {?}
                            GROUP BY  p.pid
@@ -945,6 +988,7 @@ class Profile implements PlExportable
                            $visibility->isVisible(ProfileVisibility::VIS_PRIVATE), // nickname
                            $visibility->levels(), // mobile
                            $visibility->levels(), // photo
+                           $visibility->isVisible(ProfileVisibility::VIS_PRIVATE), // deltaten_message
                            $pids
                        );
         return new ProfileIterator($it, $pids, $fields, $visibility);
index bdd1e85..3930d7e 100644 (file)
@@ -28,7 +28,7 @@ class Xorg extends Platal
                             'profile', 'register', 'search', 'stats', 'admin',
                             'newsletter', 'axletter', 'epletter', 'bandeau', 'survey',
                             'fusionax', 'gadgets', 'googleapps', 'poison',
-                            'openid', 'reminder', 'api', 'urlshortener');
+                            'openid', 'reminder', 'api', 'urlshortener', 'deltaten');
     }
 
     public function find_hook()
index a057415..ebdb03a 100644 (file)
@@ -208,6 +208,15 @@ event_forum = ""
 event_reply = ""
 
 
+; The deltaten section contains parameters used to handle the "N N-10"
+; operation.
+[Deltaten]
+
+; $globals->deltaten->first_promo_young
+; First promo to take part to the "N N-10" operation as the "young" promo
+first_promo_young = 2007
+
+
 ; The geocoder section contains parameters used to perform the geocoding 
 ; and the formatting of user addresses.
 [Geocoder]
diff --git a/modules/deltaten.php b/modules/deltaten.php
new file mode 100644 (file)
index 0000000..5695382
--- /dev/null
@@ -0,0 +1,95 @@
+<?php
+/***************************************************************************
+ *  Copyright (C) 2003-2011 Polytechnique.org                              *
+ *  http://opensource.polytechnique.org/                                   *
+ *                                                                         *
+ *  This program is free software; you can redistribute it and/or modify   *
+ *  it under the terms of the GNU General Public License as published by   *
+ *  the Free Software Foundation; either version 2 of the License, or      *
+ *  (at your option) any later version.                                    *
+ *                                                                         *
+ *  This program is distributed in the hope that it will be useful,        *
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of         *
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          *
+ *  GNU General Public License for more details.                           *
+ *                                                                         *
+ *  You should have received a copy of the GNU General Public License      *
+ *  along with this program; if not, write to the Free Software            *
+ *  Foundation, Inc.,                                                      *
+ *  59 Temple Place, Suite 330, Boston, MA  02111-1307  USA                *
+ ***************************************************************************/
+
+/** This module handles the "N N-10" operation, locally named "Delta10".
+ */
+class DeltaTenModule extends PLModule
+{
+    function handlers()
+    {
+        return array(
+            'deltaten/search'   => $this->make_hook('index', AUTH_COOKIE),
+            'deltaten'          => $this->make_hook('index', AUTH_COOKIE),
+        );
+    }
+
+    /** Check whether a given user is in a "DeltaTen" promo.
+     * This is based on "has a profile, is an X, and is in a young enough promo".
+     */
+    protected function isDeltaTenEnabled(User $user, $role)
+    {
+        if (!$user->hasProfile()) {
+            return false;
+        }
+        return $user->profile()->isDeltaTenEnabled($role);
+    }
+
+    function handler_index($page, $action='', $subaction='')
+    {
+        global $globals;
+        if (!$this->isDeltaTenEnabled(S::user(), Profile::DELTATEN_YOUNG)) {
+            $page->killError("Ta promotion ne participe pas à l'opération N N-10.");
+        }
+
+        if ($this->isDeltaTenEnabled(S::user(), Profile::DELTATEN_OLD)) {
+            $profile = S::user()->profile();
+            if ($profile->getDeltatenMessage()) {
+                $page->trigSuccess("Tu participes bien à l'opération N N-10 en tant qu'ancien.");
+            } else {
+                $page->trigWarning("Tu ne participes pas encore à l'opération N N-10 en tant qu'ancien.");
+            }
+        }
+        $page->setTitle("Opération N N-10");
+        $page->assign('deltaten_promo_old', S::user()->profile()->yearpromo() - 10);
+        $wp = new PlWikiPage('Docs.Deltaten');
+        $wp->buildCache();
+
+        require_once 'ufbuilder.inc.php';
+        $ufb = new UFB_DeltaTenSearch();
+        if (!$ufb->isEmpty()) {
+            require_once 'userset.inc.php';
+            $ufc = $ufb->getUFC();
+            if (!$ufc instanceof PFC_And) {
+                $ufc = new PFC_And($ufc);
+            }
+            $ufc->addChild(new UFC_DeltaTen());
+            $ufc->addChild(new UFC_Promo('=', UserFilter::GRADE_ING, S::user()->profile()->yearpromo() - 10));
+
+            $set = new ProfileSet($ufc);
+            $set->addMod('minifiche', 'Opération N N-10');
+            $set->apply('deltaten/search', $page, $action, $subaction);
+            $nb_tot = $set->count();
+            if ($nb_tot > $globals->search->private_max) {
+                $page->assign('formulaire', 1);
+                $page->trigError('Recherche trop générale.');
+                $page->assign('plset_count', 0);
+            } else if ($nb_tot == 0) {
+                $page->assign('formulaire', 1);
+                $page->trigError("Il n'existe personne correspondant à ces critères dans la base.");
+            }
+        }
+        $page->changeTpl('deltaten/index.tpl');
+    }
+}
+
+
+// vim:set et sw=4 sts=4 sws=4 foldmethod=marker enc=utf-8:
+?>
index 9416557..b45d510 100644 (file)
@@ -39,6 +39,7 @@ class ProfileModule extends PLModule
             'profile/networking'         => $this->make_hook('networking',                 AUTH_PUBLIC),
             'profile/ajax/job'           => $this->make_hook('ajax_job',                   AUTH_COOKIE, 'user', NO_AUTH),
             'profile/ajax/skill'         => $this->make_hook('ajax_skill',                 AUTH_COOKIE, 'user', NO_AUTH),
+            'profile/ajax/deltaten'      => $this->make_hook('ajax_deltaten',              AUTH_COOKIE, 'user', NO_AUTH),
             'profile/ajax/searchname'    => $this->make_hook('ajax_searchname',            AUTH_COOKIE, 'user', NO_AUTH),
             'profile/ajax/buildnames'    => $this->make_hook('ajax_buildnames',            AUTH_COOKIE, 'user', NO_AUTH),
             'profile/ajax/tree/jobterms' => $this->make_hook('ajax_tree_job_terms',        AUTH_COOKIE, 'user', NO_AUTH),
@@ -312,7 +313,7 @@ class ProfileModule extends PLModule
     {
         global $globals;
 
-        if (in_array($hrpid, array('general', 'adresses', 'emploi', 'poly', 'deco', 'skill', 'mentor'))) {
+        if (in_array($hrpid, array('general', 'adresses', 'emploi', 'poly', 'deco', 'skill', 'mentor', 'deltaten'))) {
             $aux = $opened_tab;
             $opened_tab = $hrpid;
             $hrpid = $aux;
@@ -347,6 +348,9 @@ class ProfileModule extends PLModule
             $wiz->addPage('ProfilePageSkills', 'Compétences diverses', 'skill');
             $wiz->addPage('ProfilePageMentor', 'Mentoring', 'mentor');
         }
+        if (S::user()->checkPerms(User::PERM_DIRECTORY_PRIVATE) && $profile->isDeltatenEnabled(Profile::DELTATEN_OLD)) {
+            $wiz->addPage('ProfilePageDeltaten', 'Opération N N-10', 'deltaten');
+        }
         $wiz->apply($page, 'profile/edit/' . $profile->hrid(), $opened_tab, $mode);
 
         if (!$profile->birthdate) {
diff --git a/modules/profile/deltaten.inc.php b/modules/profile/deltaten.inc.php
new file mode 100644 (file)
index 0000000..31ad0db
--- /dev/null
@@ -0,0 +1,67 @@
+<?php
+/***************************************************************************
+ *  Copyright (C) 2003-2011 Polytechnique.org                              *
+ *  http://opensource.polytechnique.org/                                   *
+ *                                                                         *
+ *  This program is free software; you can redistribute it and/or modify   *
+ *  it under the terms of the GNU General Public License as published by   *
+ *  the Free Software Foundation; either version 2 of the License, or      *
+ *  (at your option) any later version.                                    *
+ *                                                                         *
+ *  This program is distributed in the hope that it will be useful,        *
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of         *
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          *
+ *  GNU General Public License for more details.                           *
+ *                                                                         *
+ *  You should have received a copy of the GNU General Public License      *
+ *  along with this program; if not, write to the Free Software            *
+ *  Foundation, Inc.,                                                      *
+ *  59 Temple Place, Suite 330, Boston, MA  02111-1307  USA                *
+ ***************************************************************************/
+
+class ProfilePageDeltaten extends ProfilePage
+{
+    protected $pg_template = 'profile/deltaten.tpl';
+
+    public function __construct(PlWizard $wiz)
+    {
+        parent::__construct($wiz);
+        $this->settings['message'] = null;
+    }
+
+    protected function _fetchData()
+    {
+        $res = XDB::query('SELECT  message
+                             FROM  profile_deltaten
+                            WHERE  pid = {?}',
+                          $this->pid());
+        $this->values['message'] = $res->fetchOneCell();
+    }
+
+    protected function _saveData()
+    {
+        if ($this->changed['message']) {
+            $message = trim($this->values['message']);
+            if (empty($message)) {
+                XDB::execute('DELETE FROM  profile_deltaten
+                                    WHERE  pid = {?}',
+                             $this->pid());
+                $this->values['message'] = null;
+            } else {
+                XDB::execute('INSERT INTO  profile_deltaten (pid, message)
+                                   VALUES  ({?}, {?})
+                  ON DUPLICATE KEY UPDATE  message = VALUES(message)',
+                             $this->pid(), $message);
+                $this->values['message'] = $message;
+            }
+        }
+    }
+
+    public function _prepare(PlPage $page, $id)
+    {
+        $page->assign('hrpid', $this->profile->hrpid);
+    }
+}
+
+// vim:set et sw=4 sts=4 sws=4 foldmethod=marker enc=utf-8:
+?>
index 2bc4c52..242733f 100644 (file)
@@ -437,6 +437,7 @@ require_once dirname(__FILE__) . '/decos.inc.php';
 require_once dirname(__FILE__) . '/jobs.inc.php';
 require_once dirname(__FILE__) . '/skills.inc.php';
 require_once dirname(__FILE__) . '/mentor.inc.php';
+require_once dirname(__FILE__) . '/deltaten.inc.php';
 
 // vim:set et sw=4 sts=4 sws=4 foldmethod=marker enc=utf-8:
 ?>
diff --git a/templates/deltaten/index.tpl b/templates/deltaten/index.tpl
new file mode 100644 (file)
index 0000000..375449a
--- /dev/null
@@ -0,0 +1,424 @@
+{**************************************************************************}
+{*                                                                        *}
+{*  Copyright (C) 2003-2011 Polytechnique.org                             *}
+{*  http://opensource.polytechnique.org/                                  *}
+{*                                                                        *}
+{*  This program is free software; you can redistribute it and/or modify  *}
+{*  it under the terms of the GNU General Public License as published by  *}
+{*  the Free Software Foundation; either version 2 of the License, or     *}
+{*  (at your option) any later version.                                   *}
+{*                                                                        *}
+{*  This program is distributed in the hope that it will be useful,       *}
+{*  but WITHOUT ANY WARRANTY; without even the implied warranty of        *}
+{*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *}
+{*  GNU General Public License for more details.                          *}
+{*                                                                        *}
+{*  You should have received a copy of the GNU General Public License     *}
+{*  along with this program; if not, write to the Free Software           *}
+{*  Foundation, Inc.,                                                     *}
+{*  59 Temple Place, Suite 330, Boston, MA  02111-1307  USA               *}
+{*                                                                        *}
+{**************************************************************************}
+
+
+{if $plset_count}
+{include core=plset.tpl}
+{else}
+{include wiki=Docs.Deltaten}
+{/if}
+
+<a id="deltaten"></a>
+
+<script type="text/javascript">// <!--
+  var baseurl = $.plURL("deltaten/");
+  var baseurl_search = $.plURL("search/");
+  {literal}
+
+  // display an autocomplete row : blabla (nb of found matches)
+  function make_format_autocomplete(block) {
+    return function(row) {
+        regexp = new RegExp('(' + RegExp.escape(block.value) + ')', 'i');
+
+        name = row[0].htmlEntities().replace(regexp, '<strong>$1<\/strong>');
+
+        if (row[1] === "-1") {
+          return '&hellip;';
+        }
+
+        if (row[1] === "-2") {
+          return '<em>aucun camarade trouvé pour '+row[0].htmlEntities()+'<\/em>';
+        }
+
+        camarades = (row[1] > 1) ? "camarades" : "camarade";
+
+        return name + '<em>&nbsp;&nbsp;-&nbsp;&nbsp;' + row[1].htmlEntities() + '&nbsp;' + camarades + '<\/em>';
+      };
+  }
+
+  // when changing country, open up administrativearea choice
+  function changeCountry(a2) {
+    $(".autocompleteTarget[name='country']").attr('value',a2);
+
+    if (a2) {
+      $(".autocomplete[name='countryTxt']").addClass('hidden_valid');
+
+      $("[name='administrativearea']").parent().load(baseurl_search + 'list/administrativearea/', { country:a2 }, function() {
+          if ($("select[name='administrativearea']").children("option").size() > 1) {
+            $("select[name='administrativearea']").attr('value', '{/literal}{$smarty.request.administrativearea}{literal}');
+
+            $("tr#administrativearea_list").show();
+          } else {
+            $("select[name='administrativearea']").attr('value', '');
+
+            $("tr#administrativearea_list").hide();
+          }
+        });
+    } else {
+      $(".autocomplete[name='countryTxt']").removeClass('hidden_valid');
+
+      $("select[name='administrativearea']").attr('value', '');
+      $("select[name='subadministrativearea']").attr('value', '');
+
+      $("tr#administrativearea_list").hide();
+      $("tr#subadministrativearea_list").hide();
+    }
+  }
+
+  // when changing administrativearea, open up subadministrativearea choice
+  function changeAdministrativeArea(id) {
+    if (id) {
+      $("[name='subadministrativearea']").parent().load(baseurl_search + 'list/subadministrativearea/', { administrativearea:id }, function() {
+          if ($("select[name='subadministrativearea']").children("option").size() > 1) {
+            $("select[name='subadministrativearea']").attr('value', '{/literal}{$smarty.request.subadministrativearea}{literal}');
+            $("tr#subadministrativearea_list").show();
+          } else {
+            $("select[name='subadministrativearea']").attr('value', '');
+            $("tr#subadministrativearea_list").hide();
+          }
+        });
+    } else {
+      $("select[name='subadministrativearea']").attr('value', '');
+      $("tr#subadministrativearea_list").hide();
+    }
+  }
+
+  // when changing school, open diploma choice
+  function changeSchool(schoolId) {
+    $(".autocompleteTarget[name='school']").attr('value',schoolId);
+
+    if (schoolId) {
+      $(".autocomplete[name='schoolTxt']").addClass('hidden_valid');
+    } else {
+      $(".autocomplete[name='schoolTxt']").removeClass('hidden_valid');
+    }
+
+    $("[name='diploma']").parent().load(baseurl_search + 'list/diploma/', { school:schoolId }, function() {
+        $("select[name='diploma']").attr('value', '{/literal}{$smarty.request.diploma}{literal}');
+      });
+  }
+
+  // when choosing a job term in tree, hide tree and set job term field
+  function searchForJobTerm(treeid, jtid, full_name) {
+    $(".term_tree").remove();
+    $("input[name='jobtermTxt']").val(full_name).addClass("hidden_valid").show();
+    $("input[name='jobterm']").val(jtid);
+  }
+
+  function cancel_autocomplete(field, realfield) {
+    $(".autocomplete[name='"+field+"']").removeClass('hidden_valid').val('').focus();
+    if (typeof(realfield) != "undefined") {
+      $(".autocompleteTarget[name='"+realfield+"']").val('');
+    }
+    return;
+  }
+
+  // when choosing autocomplete from list, must validate
+  function select_autocomplete(name) {
+      nameRealField = name.replace(/Txt$/, '');
+
+      // nothing to do if field is not a text field for a list
+      if (nameRealField == name)
+        return null;
+
+      // if changing country, might want to open administrativearea choice
+      if (nameRealField == 'country')
+        return function(i) {
+            if (i.extra[0] < 0) {
+              cancel_autocomplete('countryTxt', 'country');
+              i.extra[1] = '';
+            }
+            changeCountry(i.extra[1]);
+          }
+
+      if (nameRealField == 'school')
+        return function(i) {
+            if (i.extra[0] < 0) {
+              cancel_autocomplete('schoolTxt', 'school');
+              i.extra[1] = '';
+            }
+            changeSchool(i.extra[1]);
+          }
+
+      // change field in list and display text field as valid
+      return function(i) {
+        nameRealField = this.field.replace(/Txt$/, '');
+
+        if (i.extra[0] < 0) {
+          cancel_autocomplete(this.field, nameRealField);
+          return;
+        }
+
+        $(".autocompleteTarget[name='"+nameRealField+"']").attr('value',i.extra[1]);
+
+        $(".autocomplete[name='"+this.field+"']").addClass('hidden_valid');
+      }
+    }
+
+  $(function() {
+      $(".autocompleteTarget").hide();
+      $(".autocomplete").show().each(function() {
+        targeted = $("../.autocompleteTarget",this)[0];
+
+        if (targeted && targeted.value) {
+          me = $(this);
+
+          $.get(baseurl_search + 'list/'+ targeted.name +'/'+targeted.value, {},function(textValue) {
+            me.attr('value', textValue);
+            me.addClass('hidden_valid');
+          });
+        }
+
+        $(this).autocomplete(baseurl_search + "autocomplete/"+this.name,{
+          selectOnly:1,
+          formatItem:make_format_autocomplete(this),
+          field:this.name,
+          onItemSelect:select_autocomplete(this.name),
+          matchSubset:0,
+          width:$(this).width()});
+        });
+
+      $(".autocomplete").change(function() { $(this).removeClass('hidden_valid'); });
+
+      $(".autocomplete[name='countryTxt']").change(function() { changeCountry(''); });
+
+      changeCountry({/literal}'{$smarty.request.country}'{literal});
+      changeAdministrativeArea({/literal}'{$smarty.request.administrativearea}'{literal});
+
+      $(".autocomplete[name='schoolTxt']").change(function() { changeSchool(''); });
+
+      changeSchool({/literal}'{$smarty.request.school}'{literal});
+
+      $(".autocompleteToSelect").each(function() {
+          var fieldName = $(this).attr('href');
+
+          $(this).attr('href', baseurl_search + 'list/'+fieldName).click(function() {
+              var oldval = $("input.autocompleteTarget[name='"+fieldName+"']")[0].value;
+
+              $(".autocompleteTarget[name='"+fieldName+"']").parent().load(baseurl_search + 'list/'+fieldName,{},
+                function(selectBox) {
+                  $(".autocompleteTarget[name='"+fieldName+"']").remove();
+                  $(".autocomplete[name='"+fieldName+"Txt']").remove();
+                  $("select[name='"+fieldName+"']").attr('value', oldval);
+                });
+
+              return false;
+            });
+        }).parent().find('.autocomplete').change(function() {
+          // If we change the value in the type="text" field, then the value in the 'integer id' field must not be used,
+          // to ensure that, we unset it
+          $(this).parent().find('.autocompleteTarget').val('');
+        });
+    });
+/** Regexps to wipe out from search queries */
+var default_form_values = [ /&woman=0(&|$)/, /&[^&=]+=(&|$)/g ];
+/** Uses javascript to clean form from all empty fields */
+function cleanForm(f) {
+  var query = $(f).formSerialize();
+  var old_query;
+  for (var i in default_form_values) {
+    var reg = default_form_values[i];
+    if (typeof(reg) != "undefined") {
+      do {
+        old_query = query;
+        query = query.replace(reg, '$1');
+      } while (old_query != query);
+    }
+  }
+  query = query.replace(/^&*(.*)&*$/, '$1');
+  if (query == "rechercher=Chercher") {
+    alert("Aucun critère n'a été spécifié");
+    return false;
+  }
+  document.location = baseurl + 'search?' + query;
+  return false;
+}
+-->
+{/literal}</script>
+<form id="recherche" action="deltaten/search" method="get" onsubmit="return cleanForm(this)">
+  <table class="bicol" cellpadding="3" summary="Recherche">
+    <tr>
+      <th colspan="2">
+        Opération N N-10
+      </th>
+    </tr>
+    <tr>
+      <td colspan="2" class="titre">
+      Cette recherche est effectuée uniquement au sein des membres de la promotion {$deltaten_promo_old} participant à l'opération N N-10.
+      </td>
+    </tr>
+    <tr>
+      <th colspan="2">Géographie</th>
+    </tr>
+    <tr>
+      <td>Ville ou code postal</td>
+      <td><input type="text" class="autocomplete" name="city" size="32" value="{$smarty.request.city}" /></td>
+    </tr>
+    <tr>
+      <td>Pays</td>
+      <td>
+        <input name="countryTxt" type="text" class="autocomplete" style="display:none" size="32"
+               value="{$smarty.request.countryTxt}"/>
+        <input name="country" class="autocompleteTarget" type="hidden" value="{$smarty.request.country}"/>
+        <a href="country" class="autocompleteToSelect">{icon name="table" title="Tous les pays"}</a>
+      </td>
+    </tr>
+    <tr id="administrativearea_list">
+      <td>Région, province, état&hellip;</td>
+      <td>
+        <input name="administrativearea" type="hidden" size="32" value="{$smarty.request.administrativearea}" />
+      </td>
+    </tr>
+    <tr id="subadministrativearea_list">
+      <td>Département, comté&hellip;</td>
+      <td>
+        <input name="subadministrativearea" type="hidden" size="32" value="{$smarty.request.subadministrativearea}" />
+      </td>
+    </tr>
+    <tr>
+      <td colspan="2">
+        <label for="only_current">
+          <input name="only_current" id="only_current" type="checkbox"{if $smarty.request.only_current} checked="checked"{/if}/>
+          Chercher uniquement les adresses où les camarades sont actuellement.
+        </label>
+      </td>
+    </tr>
+    <tr>
+      <th colspan="2">Activité</th>
+    </tr>
+    <tr>
+      <td>Entreprise</td>
+      <td><input type="text" class="autocomplete" name="entreprise" size="32" value="{$smarty.request.entreprise}" /></td>
+    </tr>
+    <tr>
+      <td>Description</td>
+      <td><input type="text" class="autocomplete" name="description" size="32" value="{$smarty.request.description}" /></td>
+    </tr>
+    <tr>
+      <td>Mots-clefs</td>
+      <td>
+        <input name="jobtermTxt" type="text" class="autocomplete{if $smarty.request.jobterm} hidden_valid{/if}" style="display:none" size="32"
+               value="{$smarty.request.jobtermTxt}"/>
+        <input name="jobterm" class="autocompleteTarget" type="hidden" value="{$smarty.request.jobterm}"/>
+        <a href="jobterm" class="autocompleteToSelect">{icon name="table" title="Tous les mots-clefs"}</a>
+      </td>
+    </tr>
+    <tr>
+      <th colspan="2">Divers</th>
+    </tr>
+    <tr>
+      <td>Sexe</td>
+      <td>
+        <table>
+          <tr>
+            <td style="width:100px">
+              <input type="radio" name="woman" value="0" {if !$smarty.request.woman}checked="checked"{/if} id="woman0"/><label for="woman0">indifférent</label>
+            </td>
+            <td style="width:100px">
+              <input type="radio" name="woman" value="1" {if $smarty.request.woman eq 1}checked="checked"{/if} id="woman1"/><label for="woman1">homme</label>
+            </td>
+            <td style="width:100px">
+              <input type="radio" name="woman" value="2" {if $smarty.request.woman eq 2}checked="checked"{/if} id="woman2"/><label for="woman2">femme</label>
+            </td>
+          </tr>
+        </table>
+      </td>
+    </tr>
+    <tr>
+      <td>Nationalité</td>
+      <td>
+        <input name="nationaliteTxt" type="text" class="autocomplete" style="display:none" size="32"
+               value="{$smarty.request.nationaliteTxt}"/>
+        <input name="nationalite" class="autocompleteTarget" type="hidden" value="{$smarty.request.nationalite}"/>
+        <a href="nationalite" class="autocompleteToSelect">{icon name="table" title="Toutes les nationalités"}</a>
+      </td>
+    </tr>
+    {if hasPerm('directory_private')}
+    <tr>
+      <td>Binet</td>
+      <td>
+        <input name="binetTxt" type="text" class="autocomplete" style="display:none" size="32"
+               value="{$smarty.request.binetTxt}"/>
+        <input name="binet" class="autocompleteTarget" type="hidden" value="{$smarty.request.binet}"/>
+        <a href="binet" class="autocompleteToSelect">{icon name="table" title="Tous les binets"}</a>
+      </td>
+    </tr>
+    {/if}
+    <tr>
+      <td>Groupe X</td>
+      <td>
+        <input name="groupexTxt" type="text" class="autocomplete" style="display:none" size="32"
+               value="{$smarty.request.groupexTxt}"/>
+        <input name="groupex" class="autocompleteTarget" type="hidden" value="{$smarty.request.groupex}"/>
+        <a href="groupex" class="autocompleteToSelect">{icon name="table" title="Tous les groupes X"}</a>
+      </td>
+    </tr>
+    {if hasPerm('directory_private')}
+    <tr>
+      <td>Section</td>
+      <td>
+        <input name="sectionTxt" type="text" class="autocomplete" style="display:none" size="32"
+               value="{$smarty.request.sectionTxt}"/>
+        <input name="section" class="autocompleteTarget" type="hidden" value="{$smarty.request.section}"/>
+        <a href="section" class="autocompleteToSelect">{icon name="table" title="Toutes les sections"}</a>
+      </td>
+    </tr>
+    {/if}
+    <tr>
+      <th colspan="2">Formation</th>
+    </tr>
+    <tr>
+      <td>Formation</td>
+      <td>
+        <input name="schoolTxt" type="text" class="autocomplete" style="display:none" size="32"
+               value="{$smarty.request.schoolTxt}"/>
+        <input name="school" class="autocompleteTarget" type="hidden" value="{$smarty.request.school}"/>
+        <a href="school" class="autocompleteToSelect">{icon name="table" title="Toutes les formations"}</a>
+      </td>
+    </tr>
+    <tr>
+      <td>Diplôme</td>
+      <td>
+        <input name="diploma" size="32" value="{$smarty.request.diploma}"/>
+      </td>
+    </tr>
+    <tr>
+      <th colspan="2">Opération N N-10</th>
+    </tr>
+    <tr>
+      <td>
+        Message spécifique (recherche texte)&nbsp;:
+      </td>
+      <td>
+        <input type="text" value="{$smarty.request.deltaten_message}" size="30" name="deltaten_message" />
+      </td>
+    </tr>
+    <tr><td colspan="2"></td></tr>
+    <tr>
+      <td colspan="2" style="text-align: center">
+          <input type="submit" value="Chercher" />
+      </td>
+    </tr>
+  </table>
+</form>
+
+{* vim:set et sw=2 sts=2 sws=2 enc=utf-8: *}
diff --git a/templates/profile/deltaten.tpl b/templates/profile/deltaten.tpl
new file mode 100644 (file)
index 0000000..275ea31
--- /dev/null
@@ -0,0 +1,59 @@
+{**************************************************************************}
+{*                                                                        *}
+{*  Copyright (C) 2003-2011 Polytechnique.org                             *}
+{*  http://opensource.polytechnique.org/                                  *}
+{*                                                                        *}
+{*  This program is free software; you can redistribute it and/or modify  *}
+{*  it under the terms of the GNU General Public License as published by  *}
+{*  the Free Software Foundation; either version 2 of the License, or     *}
+{*  (at your option) any later version.                                   *}
+{*                                                                        *}
+{*  This program is distributed in the hope that it will be useful,       *}
+{*  but WITHOUT ANY WARRANTY; without even the implied warranty of        *}
+{*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *}
+{*  GNU General Public License for more details.                          *}
+{*                                                                        *}
+{*  You should have received a copy of the GNU General Public License     *}
+{*  along with this program; if not, write to the Free Software           *}
+{*  Foundation, Inc.,                                                     *}
+{*  59 Temple Place, Suite 330, Boston, MA  02111-1307  USA               *}
+{*                                                                        *}
+{**************************************************************************}
+
+<table class="bicol" summary="Profil&nbsp;: Opération N N-10">
+  <tr>
+    <th>
+      <div class="flags" style="float: left">
+        <input type="checkbox" name="accesX" checked="checked" disabled="disabled" />
+        {icon name="flag_red" title="privé"}
+      </div>
+      Expériences et expertises que tu acceptes de faire partager à la promotion N+10 :
+    </th>
+  </tr>
+  <tr>
+    <td>
+      <p>
+        Si tu acceptes de participer à l'opération N N-10 pour que les camarades de la promotion plus jeune de 10 ans puisse profiter de ton expérience, il te suffit de remplir un message ci-dessous.
+        Cette démarche est complémentaire du « Mentoring », pour lequel tu trouveras plus de détails dans l'onglet dédié.
+      </p>
+
+      <p>
+        Tu peux par exemple donner des conseils sur le choix de carrière, sur ton expérience, &hellip;
+      </p>
+    </td>
+  </tr>
+  <tr>
+    <td>
+      <textarea rows="8" cols="60" name="message">{$message}</textarea>
+    </td>
+  </tr>
+  <tr>
+    <td>
+      Une fois que tu as saisi ton message, il suffit d'enregistrer les modifications en cliquant sur le bouton ci-dessous
+      pour apparaître dans la base de recherche "N N-10".
+    </td>
+  </tr>
+</table>
+
+{* vim:set et sw=2 sts=2 sws=2 enc=utf-8: *}
+
index d5eda4f..ebc782b 100644 (file)
 <div class="menu_item"><a href="groupes-x">Mes groupes X</a></div>
 {/if}
 <div class="menu_item"><a href="survey">Sondages</a></div>
+{if hasPerm('directory_private') && $smarty.session.user->hasProfile()}
+  {assign var='profile' value=$smarty.session.user->profile()}
+  {if $profile->isDeltaTenEnabled(#Profile::DELTATEN_YOUNG#)}
+    <div class="menu_item"><a href="deltaten">Opération N N-10</a></div>
+  {/if}
+{/if}
 
 <div class="menu_title">Informations</div>
 <div class="menu_item"><a href="Xorg/">Documentations</a></div>
diff --git a/upgrade/1.1.0/10_deltaten.sql b/upgrade/1.1.0/10_deltaten.sql
new file mode 100644 (file)
index 0000000..c26f3c8
--- /dev/null
@@ -0,0 +1,7 @@
+DROP TABLE IF EXISTS profile_deltaten;
+CREATE TABLE `profile_deltaten` (
+  `pid` int(11) unsigned NOT NULL DEFAULT '0',
+  `message` text NOT NULL,
+  PRIMARY KEY (`pid`),
+  CONSTRAINT FOREIGN KEY (`pid`) REFERENCES `profiles` (`pid`) ON DELETE CASCADE ON UPDATE CASCADE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8