X-Git-Url: http://git.polytechnique.org/?a=blobdiff_plain;f=modules%2Fprofile%2Fpage.inc.php;h=c6eae36768cea8288d9162f3844c4f429e54a4c5;hb=6cce7840e69bc0b6647e1bc5ea3437a925cd63a0;hp=3b0c9ca856f2e83a2fe816b2c57abcd02fe55b2b;hpb=eb5632361d837d1d4f813d4f77e52d6702a0d523;p=platal.git diff --git a/modules/profile/page.inc.php b/modules/profile/page.inc.php index 3b0c9ca..c6eae36 100644 --- a/modules/profile/page.inc.php +++ b/modules/profile/page.inc.php @@ -1,6 +1,6 @@ values[$field]) ? $page->values[$field] : S::v($field); @@ -60,9 +68,9 @@ class ProfileWeb extends ProfileNoSave } } -class ProfileEmail extends ProfileNoSave +class ProfileSettingEmail extends ProfileNoSave { - public function value(ProfilePage &$page, $field, $value, &$success) + public function value(ProfilePage $page, $field, $value, &$success) { if (is_null($value)) { return isset($page->values[$field]) ? $page->values[$field] : S::v($field); @@ -76,63 +84,118 @@ class ProfileEmail extends ProfileNoSave } } - -class ProfileTel extends ProfileNoSave +class ProfileSettingNumber extends ProfileNoSave { - public function value(ProfilePage &$page, $field, $value, &$success) + public function value(ProfilePage $page, $field, $value, &$success) { if (is_null($value)) { return isset($page->values[$field]) ? $page->values[$field] : S::v($field); } - $success = !preg_match('/[<>{}@&#~\/:;?,!§*_`\[\]|%$^=]/', $value, $matches); + $value = trim($value); + $success = empty($value) || is_numeric($value); if (!$success) { - Platal::page()->trigError('Le numéro de téléphone contient un caractère interdit : ' . pl_entities($matches[0][0])); + Platal::page()->trigError('Numéro invalide'); } return $value; } } -class ProfilePub extends ProfileNoSave +class ProfileSettingPhones implements ProfileSetting { - public function value(ProfilePage &$page, $field, $value, &$success) + public function value(ProfilePage $page, $field, $value, &$success) + { + $success = true; + $phones = array(); + + if (is_null($value)) { + $it = Phone::iterate(array($page->pid()), array(Phone::LINK_PROFILE), array(0), Visibility::defaultForEdit()); + while ($phone = $it->next()) { + $success = ($phone->format() && $success); + $phones[] = $phone->toFormArray(); + } + if (count($phones) == 0) { + $phone = new Phone(); + $phones[] = $phone->toFormArray(); + } + return $phones; + } else { + $phones = Phone::formatFormArray($value, $success); + if (!$success) { + Platal::page()->trigError('Numéro de téléphone invalide'); + } + return $phones; + } + } + + public function save(ProfilePage $page, $field, $value) + { + Phone::deletePhones($page->pid(), Phone::LINK_PROFILE, null, S::user()->isMe($page->owner) || S::admin()); + Phone::savePhones($value, $page->pid(), Phone::LINK_PROFILE); + } + + public function getText($value) + { + return Phone::formArrayToString($value); + } +} + +class ProfileSettingPub extends ProfileNoSave +{ + public function value(ProfilePage $page, $field, $value, &$success) { $success = true; if (is_null($value)) { return isset($page->values[$field]) ? $page->values[$field] : S::v($field); } - if (is_null($value) || !$value) { + if (!$value) { $value = 'private'; - } else if ($value == 'on') { // Checkbox + } elseif ($value == 'on') { // Checkbox $value = 'public'; } return $value; } + + public function getText($value) { + static $pubs = array('public' => 'publique', 'ax' => 'annuaire AX', 'private' => 'privé'); + return $pubs[$value]; + } } -class ProfileBool extends ProfileNoSave +class ProfileSettingBool extends ProfileNoSave { - public function value(ProfilePage &$page, $field, $value, &$success) + public function value(ProfilePage $page, $field, $value, &$success) { $success = true; if (is_null($value)) { - $value = @$page->values[$field]; + $value = isset($page->values[$field]) ? $page->values[$field] : null; } return $value ? "1" : ""; } } -class ProfileDate extends ProfileNoSave +class ProfileSettingDate extends ProfileNoSave { - public function value(ProfilePage &$page, $field, $value, &$success) + private $allowEmpty; + + public function __construct($allowEmpty = false) + { + $this->allowEmpty = $allowEmpty; + } + + public function value(ProfilePage $page, $field, $value, &$success) { $success = true; if (is_null($value)) { $value = preg_replace('/(\d{4})-(\d{2})-(\d{2})/', '\3/\2/\1', @$page->values[$field]); } else { + $value = trim($value); + if (empty($value) && $this->allowEmpty) { + return null; + } $success = preg_match('@(\d{2})/(\d{2})/(\d{4})@', $value, $matches); if (!$success) { Platal::page()->trigError("Les dates doivent être au format jj/mm/aaaa"); - } else { + } else { $day = (int)$matches[1]; $month = (int)$matches[2]; $year = (int)$matches[3]; @@ -144,50 +207,13 @@ class ProfileDate extends ProfileNoSave } return $value; } -} -abstract class ProfileGeoloc implements ProfileSetting -{ - protected function geolocAddress(array &$address, &$success) + public static function toSQLDate($value) { - require_once 'geoloc.inc.php'; - $success = true; - unset($address['geoloc']); - unset($address['geoloc_cityid']); - if (@$address['parsevalid'] - || (@$address['text'] && @$address['changed']) - || (@$address['text'] && !@$address['cityid'])) { - $address = array_merge($address, empty_address()); - $new = get_address_infos(@$address['text']); - if (compare_addresses_text(@$address['text'], $geotxt = get_address_text($new)) - || (@$address['parsevalid'] && @$address['cityid'])) { - $address = array_merge($address, $new); - $address['checked'] = true; - } else if (@$address['parsevalid']) { - $address = array_merge($address, cut_address(@$address['text'])); - $address['checked'] = true; - $mailer = new PlMailer('geoloc/geoloc.mail.tpl'); - $mailer->assign('text', get_address_text($address)); - $mailer->assign('geoloc', $geotxt); - $mailer->send(); - } else if (@$address['changed'] || !@$address['checked']) { - $success = false; - $address = array_merge($address, cut_address(@$address['text'])); - $address['checked'] = false; - $address['geoloc'] = $geotxt; - $address['geoloc_cityid'] = $new['cityid']; - } else { - $address = array_merge($address, cut_address(@$address['text'])); - $address['checked'] = true; - } - } - $address['precise_lat'] = rtrim($address['precise_lat'], '.0'); - $address['precise_lon'] = rtrim($address['precise_lon'], '.0'); - $address['text'] = get_address_text($address); + return preg_replace('@(\d{2})/(\d{2})/(\d{4})@', '\3-\2-\1', $value); } } - abstract class ProfilePage implements PlWizardPage { protected $wizard; @@ -199,10 +225,14 @@ abstract class ProfilePage implements PlWizardPage public $orig = array(); public $values = array(); + public $profile = null; + public $owner = null; - public function __construct(PlWizard &$wiz) + public function __construct(PlWizard $wiz) { $this->wizard =& $wiz; + $this->profile = $this->wizard->getUserData('profile'); + $this->owner = $this->wizard->getUserData('owner'); } protected function _fetchData() @@ -233,27 +263,60 @@ abstract class ProfilePage implements PlWizardPage { } - protected function saveData() + public function saveData() { require_once 'notifs.inc.php'; + $changedFields = array(); foreach ($this->settings as $field=>&$setting) { - if (!is_null($setting) && $this->changed[$field]) { - $setting->save($this, $field, $this->values[$field]); - } - if ($this->changed[$field] && @$this->watched[$field]) { - register_profile_update(S::i('uid'), $field); + if ($this->changed[$field]) { + if (!is_null($setting)) { + $changedFields[$field] = array( + preg_replace('/(\r\n|\n|\r)/', ' - ', $setting->getText($this->orig[$field])), + preg_replace('/(\r\n|\n|\r)/', ' - ', $setting->getText($this->values[$field])), + ); + } else { + $changedFields[$field] = array( + preg_replace('/(\r\n|\n|\r)/', ' - ', $this->orig[$field]), + preg_replace('/(\r\n|\n|\r)/', ' - ', $this->values[$field]), + ); + } + if (!is_null($setting)) { + $setting->save($this, $field, $this->values[$field]); + } + if (isset($this->watched[$field]) && $this->watched[$field]) { + WatchProfileUpdate::register($this->profile, $field); + } } } $this->_saveData(); // Update the last modification date - XDB::execute('REPLACE INTO user_changes - SET user_id = {?}', S::v('uid')); - if (!S::has('suid')) { - register_watch_op(S::i('uid'), WATCH_FICHE); - } + XDB::execute('UPDATE profiles + SET last_change = NOW() + WHERE pid = {?}', $this->pid()); global $platal; - S::logger()->log('profil', $platal->pl_self(1)); + S::logger()->log('profil', $platal->pl_self(2)); + + /** Stores all profile modifications for active users in order to: + * -daily notify the user in case of third party edition, + * -display the modification to the secretaries for verification in + * case of an edition made by the user. + */ + $owner = $this->profile->owner(); + $user = S::user(); + if ($owner->isActive()) { + foreach ($changedFields as $field => $values) { + if (in_array($field, Profile::$descriptions)) { + XDB::execute('INSERT INTO profile_modifications (pid, uid, field, oldText, newText, type, timestamp) + VALUES ({?}, {?}, {?}, {?}, {?}, {?}, NOW()) + ON DUPLICATE KEY UPDATE uid = VALUES(uid), oldText = IF(VALUES(type) != type, VALUES(oldText), oldText), + newText = VALUES(newText), type = VALUES(type), timestamp = NOW()', + $this->pid(), $user->id(), Profile::$descriptions[$field], $values[0], $values[1], + ($owner->id() == $user->id()) ? 'self' : 'third_party'); + } + } + } + return true; } protected function checkChanges() @@ -283,11 +346,21 @@ abstract class ProfilePage implements PlWizardPage return 'profile/base.tpl'; } - protected function _prepare(PlPage &$page, $id) + public function pid() { + return $this->profile->id(); } - public function prepare(PlPage &$page, $id) + public function hrpid() + { + return $this->profile->hrpid(); + } + + protected function _prepare(PlPage $page, $id) + { + } + + public function prepare(PlPage $page, $id) { if (count($this->values) == 0) { $this->fetchData(); @@ -296,6 +369,8 @@ abstract class ProfilePage implements PlWizardPage $page->assign($field, $value); } $this->_prepare($page, $id); + $page->assign('profile', $this->profile); + $page->assign('owner', $this->owner); $page->assign('profile_page', $this->pg_template); $page->assign('errors', $this->errors); } @@ -317,19 +392,41 @@ abstract class ProfilePage implements PlWizardPage } if ($global_success) { if ($this->checkChanges()) { - $this->saveData(); + /* Save changes atomically to avoid inconsistent state + * in case of error. + */ + if (!XDB::runTransaction(array($this, 'saveData'))) { + $global_success = false; + return PlWizard::CURRENT_PAGE; + } $this->markChange(); } + // XXX: removes this code once all merge related issues have been fixed. + static $issues = array(0 => array('name', 'promo', 'phone', 'education'), 1 => array('address'), 2 => array('job')); + if (isset($issues[Post::i('valid_page')])) { + foreach ($issues[Post::i('valid_page')] as $issue) { + XDB::execute("UPDATE profile_merge_issues + SET issues = REPLACE(issues, {?}, '') + WHERE pid = {?}", + $issue, $this->pid()); + } + } return Post::has('next_page') ? PlWizard::NEXT_PAGE : PlWizard::CURRENT_PAGE; } - Platal::page()->trigError("Certains champs n'ont pas pu être validés, merci de corriger les informations " - . "de ton profil et de revalider ta demande."); + $text = "Certains champs n'ont pas pu être validés, merci de corriger les informations " + . (S::user()->isMe($this->owner) ? "de ton profil et de revalider ta demande." + : "du profil et de revalider ta demande."); + Platal::page()->trigError($text); return PlWizard::CURRENT_PAGE; } public function success() { - return 'Ton profil a bien été mis à jour.'; + if (S::user()->isMe($this->owner)) { + return 'Ton profil a bien été mis à jour.'; + } else { + return 'Le profil a bien été mis à jour.'; + } } } @@ -340,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: ?>