/** * Adds given address to given mailing list. * @param string listname * @param string email * @return boolean status (true=success, false=failure) */ public static function subscribe($listname, $email) { $conn = sfDoctrine::Connection(); try { $conn->beginTransaction(); $sympa = new Sympa(); $sympa->list_subscriber = $listname; $sympa->user_subscriber = $email; $sympa->save(); $conn->commit(); return true; } catch (Exception $e) { // Subscription failed! For instance because email address was already registered. $conn->rollback(); c2cTools::log("Failed adding address {$email} to list {$listname}: " . $e->getMessage()); return false; } }
/** * Changes the association order for associations of same type (eg summit-summit) * It should only be used for ss, pp and tt associations, but there is probably * no real problem if other associations are inverted */ public function executeInvertAssociation() { $user = $this->getUser(); $user_id = $user->getId(); $is_moderator = $user->hasCredential('moderator'); $type = $this->getRequestParameter('type'); $main_id = $this->getRequestParameter('main_id'); $linked_id = $this->getRequestParameter('linked_id'); // check if session timed out if (!$user_id) { return $this->setErrorAndRedirect('Session is over. Please login again.', $this->getRequest()->getReferer()); } // only moderators can perform such actions if (!$is_moderator) { return $this->setErrorAndRedirect('You do not have enough credentials to perform this operation', $this->getRequest()->getReferer()); } // we check that the association type really exists and that the two // documents are from the same model if (substr($type, 0, 1) != substr($type, -1) || !in_array($type, sfConfig::get('app_associations_types'))) { return $this->ajax_feedback('Wrong association type'); } // check that association exists in database $models = c2cTools::Type2Models($type); $model = $models['main']; $module = c2cTools::model2module($model); $a = Association::find($main_id, $linked_id, $type); // strict search if (!$a) { return $this->setErrorAndRedirect('Operation not allowed', $this->getRequest()->getReferer()); } // invert association $conn = sfDoctrine::Connection(); try { $conn->beginTransaction(); $a->main_id = $linked_id; $a->linked_id = $main_id; $a->save(); $al1 = new AssociationLog(); $al1->main_id = $main_id; $al1->linked_id = $linked_id; $al1->type = $type; $al1->user_id = $user_id; $al1->is_creation = 'false'; $al1->save(); $al1 = new AssociationLog(); $al1->main_id = $linked_id; $al1->linked_id = $main_id; $al1->type = $type; $al1->user_id = $user_id; $al1->is_creation = 'true'; $al1->save(); $conn->commit(); } catch (exception $e) { $conn->rollback(); c2cTools::log("executeInvertAssociation() : invertion failed ({$main_id}, {$linked_id}, {$type}, {$user_id}) - rollback"); return $this->ajax_feedback('Association invertion failed'); } // remove cache and force page reload $this->clearCache($module, $main_id, false, 'view'); $this->clearCache($module, $linked_id, false, 'view'); return $this->setNoticeAndRedirect('Association inverted', $this->getRequest()->getReferer()); }
public function doSaveWithValues($main_id, $linked_id, $type, $user_id) { $conn = sfDoctrine::Connection(); try { $conn->beginTransaction(); // we create the association: $this->main_id = $main_id; $this->linked_id = $linked_id; $this->type = $type; $this->save(); // and we log this: $al = new AssociationLog(); $al->main_id = $main_id; $al->linked_id = $linked_id; $al->type = $type; $al->user_id = $user_id; $al->is_creation = true; $al->save(); $conn->commit(); // send an email to moderators if a picture is associated to a book if ($type == 'bi') { try { // retrieve moderators email $moderator_id = sfConfig::get('app_moderator_user_id'); // currently send to topo-fr only $conn->beginTransaction(); $rows = $conn->standaloneQuery('SELECT email FROM app_users_private_data d WHERE id = ' . $moderator_id)->fetchAll(); $conn->commit(); $email_recipient = $rows[0]['email']; $mail = new sfMail(); $mail->setCharset('utf-8'); // definition of the required parameters $mail->setSender(sfConfig::get('app_outgoing_emails_sender')); $mail->setFrom(sfConfig::get('app_outgoing_emails_from')); $mail->addReplyTo(sfConfig::get('app_outgoing_emails_reply_to')); $mail->addAddress($email_recipient); $mail->setSubject('New image associated to book'); $mail->setContentType('text/html'); $server = $_SERVER['SERVER_NAME']; $body = "<p>A <a href=\"http://{$server}/images/{$linked_id}\">new image</a> has been associated to <a href=\"http://{$server}/books/{$main_id}\">book {$main_id}</a>.</p>" . "<p>The image may require a copyright license. If so, please ensure that:</p>" . "<ul>" . "<li>the owner is correctly acknowledged in the author field;</li>" . "<li>the image is not too big (max 800px width or height).</li>" . "</ul>"; $mail->setBody($body); // send the email $mail->send(); } catch (exception $e) { $conn->rollback(); c2cTools::log("Association::doSaveWithValues({$main_id}, {$linked_id}, {$type}, {$user_id}) failed sending email for image associated to book"); } } return true; } catch (exception $e) { $conn->rollback(); c2cTools::log("Association::doSaveWithValues({$main_id}, {$linked_id}, {$type}, {$user_id}) failed - rollback"); return false; } }
public static function getLinkedFiles($id) { $filename_rows = sfDoctrine::Connection()->standaloneQuery('SELECT DISTINCT filename FROM app_images_archives WHERE id = ?', array($id))->fetchAll(); $filenames = array(); foreach ($filename_rows as $row) { $filenames[] = $row['filename']; } return $filenames; }
public function signIn($login_name, $password, $remember = false, $password_is_hashed = false) { c2cTools::log('in signin function from myUser class'); $return = false; // we need to retrieve the stored hash for the correspondings user to: // - the salt is stored there, needed for verifiying the password // - allows us to check whether it is still an old hash, without salt $upd = UserPrivateData::retrieveByLoginName($login_name); if (!$upd) { return false; } else { $userid = $upd->id; $hash_tmp = $upd->password_tmp; $hash = $upd->password; } if ($password_is_hashed) { $user = $password === $hash ? sfDoctrine::getTable('User')->find($userid) : false; } else { $user = self::check_password($password, $hash) ? sfDoctrine::getTable('User')->find($userid) : false; } // maybe the user requested a new password, check if password_tmp is ok if (!$user && !$password_is_hashed) { // This block is not used when password is hashed. Indeed password is hashed only // when performing an automatic signIn ("remember me"). // In that case, no temp password is used. c2cTools::log('base login failed, start trying with password_temp'); // user not found, try with tmp password $user = self::check_password($password, $hash_tmp) ? sfDoctrine::getTable('User')->find($userid) : false; if ($user) { c2cTools::log('user found, make temp password the new password'); // user used his tmp password $user_private_data = $user->get('private_data'); // set password to tmp password $user_private_data->set('password', $password); // delete tmp password $user_private_data->set('password_tmp', null); $user->save(); } } if ($user) { c2cTools::log('user found, continue to test if active'); if ($user->isActive()) { c2cTools::log('user is active'); $user_id = $user->get('id'); // if we went there with the old hash algorithm (simple hash, no salt), // then update the db with so that we use the new algorithm next time if (!$password_is_hashed && password_needs_rehash($hash, PASSWORD_DEFAULT)) { c2cTools::log('upgrading user to new hash algorithm'); $conn = sfDoctrine::Connection(); try { $user_private_data = UserPrivateData::find($user_id); $user_private_data->setPassword($password); $user_private_data->save(); $conn->commit(); } catch (Exception $e) { $conn->rollback(); c2cTools::log('could not upgrade user to new hash algorithm'); } $hash = $user_private_data->getPassword(); } $user_culture = $user->get('private_data')->getPreferedCulture(); // when user signs-in it confirms his signup if ($user->isConfirmationPending()) { c2cTools::log('remove user from pending group'); $user->removeFromGroup('pending'); } // login punbb if ($password_is_hashed) { Punbb::signIn($user_id, $password); } else { Punbb::signIn($user_id, $hash); } c2cTools::log('logged in punbb'); // remember? if ($remember) { c2cTools::log('remember me requested / or renew'); $context = sfContext::getInstance(); $remember_cookie = sfConfig::get('app_remember_key_cookie_name', 'c2corg_remember'); $key = RememberKey::generateRandomKey(); // if remember_cookie was set in the request, it means that we are renewing it $remember_key = $context->getRequest()->getCookie($remember_cookie); if ($remember_key) { RememberKey::renewKey($remember_key, $key); } else { $rk = new RememberKey(); $rk->set('remember_key', $key); $rk->set('user', $user); $rk->set('ip_address', isset($_SERVER['HTTP_X_ORIGIN_IP']) ? $_SERVER['HTTP_X_ORIGIN_IP'] : $_SERVER['REMOTE_ADDR']); // TODO remove obsolete field $rk->save(); } // TODO : move remove old keys in a batch // remove old keys RememberKey::deleteOldKeys(); // make key as a cookie $expiration_age = sfConfig::get('app_remember_key_expiration_age', 30 * 24 * 3600); $context->getResponse()->setCookie($remember_cookie, $key, time() + $expiration_age, '/', '', false, true); } else { // user is authenticated but has not checked "remember me" option // let's add a cookie to indicate his/her session should not be reset while his/her browser is open sfContext::getInstance()->getResponse()->setCookie('temp_remember', 1); } c2cTools::log('add some information in user session'); // give credentials $this->addCredentials($user->getAllPermissionNames()); // login session symfony $this->setAttribute('username', $user->get('private_data')->get('topo_name')); $this->setAttribute('id', $user_id); // set the prefered language for user session // and the list of languages ordered by preference $this->saveLanguageListInSession($user->get('private_data')->getDocumentCulture()); // set logged $this->setAuthenticated(true); $return = true; // change language session if needed if ($this->getCulture() != $user_culture) { $this->setCulture($user_culture); } // be sure to update punbb language cookie Punbb::setLanguage($user_culture); // Restore pref cookies c2cPersonalization::restorePrefCookies($user_id); } } return $return; }
echo ' Create association with image ' . $image_data['id'] . "\n"; } if (!$DRY_RUN) { $asso = new Association(); $asso->doSaveWithValues($doc['id'], $image_data['id'], $association_type, $TOPO_MODERATOR_USER_ID); } $stat_associations_required++; } $image_ids[$tag[1]] = $image_data['id']; } else { // no corresponding id, the tag is incorrect and must not be modified. but a warning should be notified $stat_docs_with_invalid_references[] = $doc['id'] . ' (' . $doc['culture'] . ' - ' . $doc['name'] . ') http://' . $SERVER_NAME . '/' . strtolower($table) . 's' . '/' . $doc['id'] . '/' . $doc['culture'] . "\n"; } } // replace image tags $conn = sfDoctrine::Connection(); $db_doc = Document::find($table, $doc['id']); if (!$DRY_RUN) { $conn->beginTransaction(); $history_metadata = new HistoryMetadata(); $history_metadata->setComment('Updated image tags'); $history_metadata->set('is_minor', true); $history_metadata->set('user_id', $TOPO_MODERATOR_USER_ID); $history_metadata->save(); $db_doc->setCulture($doc['culture']); } foreach ($fields as $field) { $tag_data = $tags_for_field[$field]; $text = $doc[$field]; foreach ($tag_data as $tag_idx) { $references_to_modify++;
public function executeAddroute() { $id = $this->getRequestParameter('document_id'); // check if a summit is already associated to hut. if not, create it $create_summit = Association::countMains($id, 'sh') == 0; if ($create_summit) { $document = Document::find('Hut', $id, array('elevation', 'geom_wkt')); $conn = sfDoctrine::Connection(); try { $conn->beginTransaction(); // create first version of document, with culture and geometry of hut document $hut_elevation = $document['elevation']; $hut_lat = $document['lat']; $hut_lon = $document['lon']; $hut_culture = $document->getCulture(); $hut_name = $document['name']; $history_metadata = new HistoryMetadata(); $history_metadata->setComment($this->__('Created summit synchronized with hut for access')); $history_metadata->set('is_minor', false); $history_metadata->set('user_id', 2); // C2C user $history_metadata->save(); $summit = new Summit(); $summit->setCulture($hut_culture); $summit->set('name', $hut_name); $summit->set('elevation', $hut_elevation); $summit->set('summit_type', 100); // set summit type to ' hut' $summit->set('lat', $hut_lat); $summit->set('lon', $hut_lon); $summit->save(); $conn->commit(); // add others culture versions foreach ($document->get('HutI18n') as $i18n) { $culture = $i18n->getCulture(); if ($culture != $hut_culture) { $conn->beginTransaction(); $hut_name = $i18n->getName(); $history_metadata = new HistoryMetadata(); $history_metadata->setComment($this->__('Created summit synchronized with hut for access')); $history_metadata->set('is_minor', false); $history_metadata->set('user_id', 2); // C2C user $history_metadata->save(); $summit->setCulture($culture); $summit->set('name', $hut_name); $summit->save(); $conn->commit(); } } } catch (Exception $e) { $conn->rollback(); return $this->setErrorAndRedirect($this->__('Failed to create synchronized summit'), "routes/edit?link={$summit_id}"); } $summit_id = $summit->get('id'); // get all associated regions (3+maps) with this hut: $associations = GeoAssociation::findAllAssociations($id, array('dr', 'dc', 'dd', 'dv', 'dm')); // replicate them with summit_id instead of id: foreach ($associations as $ea) { $a = new GeoAssociation(); $a->doSaveWithValues($summit_id, $ea->get('linked_id'), $ea->get('type')); } // associate hut to summit $asso = new Association(); $asso->doSaveWithValues($summit_id, $id, 'sh', 2); // C2C user } else { $associations = Association::findAllAssociations($id, 'sh'); $summit_id = $associations[0]->get('main_id'); } $this->clearCache('huts', $id); return $this->redirect("routes/edit?link={$summit_id}"); }
public function executeManageimages() { if (!$this->getUser()->isConnected()) { $referer = $this->getRequest()->getReferer(); $this->setErrorAndRedirect('You need to login to access this page', $referer); } $user_id = $this->getUser()->getId(); // logged user id $this->pager = new c2cDoctrinePager('Image', c2cTools::mobileVersion() ? sfConfig::get('app_list_mobile_maxline_number') : sfConfig::get('app_list_maxline_number')); $q = $this->pager->getQuery(); $q->select('i.id, i.filename, i.image_type, ii.name, ii.culture')->from('Image i')->leftJoin('i.associations a ON i.id = a.linked_id')->leftJoin('i.ImageI18n ii')->leftJoin('i.versions v')->leftJoin('v.history_metadata hm'); $where = 'i.image_type = 2 AND v.version = 1 AND hm.user_id = ?'; $document_type = $this->getRequestParameter('dtyp'); if (!empty($document_type)) { if ($document_type <= 1) { $types = array('ai', 'mi', 'bi', 'hi', 'pi', 'ri', 'ti', 'si'); } else { $types = array('oi', 'ui'); } $where .= " AND a.type IN ( '" . implode("', '", $types) . "' )"; } else { $document_type = $this->getRequestParameter('ctyp'); if (!empty($document_type)) { $q->leftJoin('a.Article c'); if ($document_type <= 1) { $document_type = 1; } else { $document_type = 2; } $where .= " AND a.type = 'ci' AND c.article_type = {$document_type}"; } } $q->where($where, array($user_id)); $q->orderBy('i.id DESC'); $page = $this->getRequestParameter('page', 1); $this->pager->setPage($page); $this->pager->init(); $this->page = $page; if ($this->getRequest()->getMethod() == sfRequest::POST) { // images management $switch = $this->getRequestParameter('switch'); $lang = $this->getUser()->getCulture(); if (empty($switch)) { return $this->setNoticeAndRedirect('No image has been edited', "/users/manageimages?module=users&page={$page}"); } $conn = sfDoctrine::Connection(); $conn->beginTransaction(); $history_metadata = new HistoryMetadata(); $history_metadata->setComment('Switch to collaborative license'); $history_metadata->set('is_minor', true); $history_metadata->set('user_id', $user_id); $history_metadata->save(); foreach ($switch as $image_id) { // verify id corresponds to an image created by the user $img = Doctrine_Query::create()->select('i.id')->from('Image i')->leftJoin('i.versions v')->leftJoin('v.history_metadata hm')->where('v.version = 1 AND hm.user_id = ? AND i.id = ?', array($user_id, $image_id))->execute(); if (empty($img)) { $conn->rollback(); return $this->setNoticeAndRedirect('You do not have the right to change the license of theses images', "/users/manageimages?module=users&page={$page}"); } $db_doc = Document::find('Image', $image_id); $db_doc->set('image_type', 1); $db_doc->save(); // clear cache $this->clearCache('images', $image_id, false, 'view'); $associated_docs = Association::findAllAssociatedDocs($image_id, array('id', 'module')); foreach ($associated_docs as $doc) { // clear their view cache $this->clearCache($doc['module'], $doc['id'], false, 'view'); } } // apply modifications if everything went fine $conn->commit(); return $this->setNoticeAndRedirect('Your images have been successfully updated', "/users/manageimages?module=users&page={$page}"); } else { // display form $this->setPageTitle($this->__('User image management')); } }
protected function doMerge($from_id, $document_from, $to_id, $document_to) { // fetch associated documents before doing the merging as associations will be transferred $associations = Association::findAllAssociations($from_id); parent::doMerge($from_id, $document_from, $to_id, $document_to); // search documents in which from is inserted, and replace the insertion with to foreach ($associations as $a) { $check_id = $a['main_id'] == $from_id ? $a['linked_id'] : ($check_id = $a['main_id']); $check_model = c2cTools::Letter2Model(substr($a['type'], 0, 1)); $check_module = c2cTools::Model2Module($check_model); $check_doc = Document::find($check_model, $check_id); $fields = sfConfig::get('mod_images_bbcode_fields_' . $check_module); // clear linked doc cache $this->clearCache($check_module, $check_id); $languages = $check_doc->getLanguages(); foreach ($languages as $language) { $modified = false; $conn = sfDoctrine::Connection(); $conn->beginTransaction(); $check_doc->setCulture($language); foreach ($fields as $field) { $text = $check_doc[$field]; $edited = preg_replace('#(\\[img=\\s*)' . $from_id . '([\\w\\s]*\\].*?\\[/img\\])\\n?#is', '${1}' . $to_id . '${2}', $text); $edited = preg_replace('#(\\[img=\\s*)' . $from_id . '([\\w\\s]*\\/\\])\\n?#is', '${1}' . $to_id . '${2}', $edited); if ($edited != $text) { $modified = true; $check_doc->set($field, $edited); } } if ($modified) { $history_metadata = new HistoryMetadata(); $history_metadata->setComment('Updated image tags'); $history_metadata->set('is_minor', true); $history_metadata->set('user_id', sfConfig::get('app_moderator_user_id')); $history_metadata->save(); c2cTools::log('After merge of image ' . $from_id . ' into ' . $to_id . ': update image tag for ' . strtolower($check_model) . ' ' . $check_id . ' (' . $language . ')'); $check_doc->save(); $conn->commit(); } else { $conn->rollback(); } } } // clear images lists and whatsnew cache $this->clearCache('images', 0, true); }
/** * restore cookie values from profile. Managed cookies not in the profile will be deleted */ public static function restorePrefCookies($user_id) { if (!($user_private_data = UserPrivateData::find($user_id))) { return; // silently stop } $response = sfContext::getInstance()->getResponse(); $managed_cookies = sfConfig::get('app_profile_cookies_list'); $fold_prefs = sfConfig::get('app_personalization_cookie_fold_positions'); $cookie_prefs = $user_private_data->getPref_cookies(); if (empty($cookie_prefs)) { // no saved value in profile, copy the current cookie values into profile // 'regular' cookies $cookie_values = array(); foreach ($managed_cookies as $cookie) { if (sfContext::getInstance()->getRequest()->getCookie($cookie)) { $cookie_values[$cookie] = urlencode(sfContext::getInstance()->getRequest()->getCookie($cookie)); } } // fold prefs if (sfContext::getInstance()->getRequest()->getCookie('fold')) { $fold_cookie_value = sfContext::getInstance()->getRequest()->getCookie('fold'); foreach ($fold_prefs as $pos => $pref) { if ($fold_cookie_value[$pos] == 't') { $cookie_values[$pref + '_home_status'] = 'true'; } else { if ($fold_cookie_value[$pos] == 'f') { $cookie_values[$pref + '_home_status'] = 'false'; } } } } if (!empty($cookie_values)) { $conn = sfDoctrine::Connection(); try { $user_private_data->setPref_cookies($cookie_values); $user_private_data->save(); $conn->commit(); } catch (Exception $e) { $conn->rollback(); } } } else { // set fold cookie $fold_cookie_value = $default = str_repeat('x', sfConfig::get('app_personalization_cookie_fold_size')); foreach ($fold_prefs as $pos => $pref) { if (isset($cookie_prefs[$pref . '_home_status'])) { $fold_cookie_value[$pos] = $cookie_prefs[$pref . '_home_status'] == 'true' ? 't' : 'f'; } } if ($fold_cookie_value != $default) { $response->setCookie('fold', $fold_cookie_value, time() + sfConfig::get('app_personalization_filter_timeout')); } else { $response->setCookie('fold', ''); } // erase all managed cookies or replace values with the one in profile foreach ($managed_cookies as $cookie_name) { if (array_key_exists($cookie_name, $cookie_prefs)) { $response->setCookie($cookie_name, $cookie_prefs[$cookie_name], time() + sfConfig::get('app_personalization_filter_timeout')); } else { $response->setCookie($cookie_name, ''); } } } }
/** * Saves new data for the document with its metadata. * */ public function doSaveWithMetadata($user_id, $is_minor = false, $comment = null) { $conn = sfDoctrine::Connection(); try { $conn->beginTransaction(); // history metadata saving here $history_metadata = new HistoryMetadata(); $history_metadata->setComment($comment); $history_metadata->set('is_minor', $is_minor); $history_metadata->set('user_id', $user_id); // data saving must be done in this order : $history_metadata->save(); $this->save(); $conn->commit(); return true; } catch (exception $e) { $conn->rollback(); throw $e; } }