/**
  * 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());
 }
 protected function endEdit()
 {
     //Test if form is submitted or not
     if ($this->success) {
         // try to perform association with linked_doc (if pertinent)
         $summit_id = $this->getRequestParameter('summit_id');
         $id = $this->document->get('id');
         $user_id = $this->getUser()->getId();
         if ($this->new_document && $summit_id || $summit_id && !Association::find($summit_id, $id, 'sr')) {
             $sr = new Association();
             $sr->doSaveWithValues($summit_id, $id, 'sr', $user_id);
             // main, linked, type
             // clear cache of associated summit ...
             $this->clearCache('summits', $summit_id, false, 'view');
         }
         // here if we have created a new document and if $this->document->get('geom_wkt') is null, then use associated doc geom associations:
         // this allows us to filter on ranges even if no GPX is uploaded
         if ($this->new_document && $summit_id && !$this->document->get('geom_wkt')) {
             // get all associated regions (3+maps) with this summit:
             $associations = GeoAssociation::findAllAssociations($summit_id, array('dr', 'dc', 'dd', 'dv', 'dm'));
             // replicate them with route_id instead of summit_id:
             foreach ($associations as $ea) {
                 $a = new GeoAssociation();
                 $a->doSaveWithValues($id, $ea->get('linked_id'), $ea->get('type'));
             }
         }
         // if we add a route to a summit-hut, link the route to the hut
         $hut_asso = Association::findAllAssociations($summit_id, 'sh');
         if ($this->new_document && $summit_id && count($hut_asso) > 0) {
             // associate hut to summit
             $asso = new Association();
             $hut_id = $hut_asso[0]->get('linked_id');
             $asso->doSaveWithValues($hut_id, $id, 'hr', 2);
             // C2C user
             // clear cache of associated hut ...
             $this->clearCache('huts', $hut_id, false, 'view');
         }
         parent::endEdit();
         // redirect to document view
     } else {
         if ($this->link_with = $this->getRequestParameter('link')) {
             // linked_doc was already retrieved in filterAdditionalParameters
             if ($this->linked_doc) {
                 $this->linked_doc->setBestCulture($this->getUser()->getCulturesForDocuments());
             }
         } else {
             $this->linked_doc = $this->getHighestSummit();
         }
     }
 }
 /**
  * filter for people who have the right to edit current document (linked people for outings, original editor for articles ....)
  * overrides the one in parent class.
  */
 protected function filterAuthorizedPeople($id)
 {
     // we know here that document $id exists and that its model is the current one (Outing).
     // we must guess the associated people and restrain edit rights to these people + moderator.
     $user = $this->getUser();
     $a = Association::find($user->getId(), $id, 'uo');
     if (!$a && !$user->hasCredential('moderator')) {
         $referer = $this->getRequest()->getReferer();
         $this->setErrorAndRedirect('You do not have the rights to edit this outing', $referer);
     }
 }
         $tags[$l][3] = $matches[$i][6];
         array_push($tags_for_field[$field], $l);
     }
 }
 // get image ids corresponding to filenames, create required associations
 $image_ids = array();
 foreach ($tags as $tag) {
     if (empty($tag[1]) || !empty($image_ids[$tag[1]])) {
         continue;
     }
     // get image id corresponding to filename
     $query = Doctrine_Query::create()->select('i.id')->from('Image i')->where('filename = \'' . $tag[1] . "'");
     $image_data = $query->execute()->getFirst();
     if (!empty($image_data)) {
         // does the relation already exists, or should it be created?
         $association = Association::find($doc['id'], $image_data['id'], $association_type, true);
         if (empty($association)) {
             // create association
             if ($DEBUG) {
                 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";
 private function checkUploadRights()
 {
     $document_id = $this->getRequestParameter('document_id');
     $mod = $this->getRequestParameter('mod');
     $request = $this->getRequest();
     $user = $this->getUser();
     $user_id = $user->getId();
     $user_valid = true;
     switch ($mod) {
         case 'users':
             if ($user_id != $document_id) {
                 $user_valid = false;
             }
             break;
         case 'outings':
             if (!Association::find($user_id, $document_id, 'uo')) {
                 $user_valid = false;
             }
             break;
         case 'images':
             $image = Document::find('Image', $document_id, array('image_type'));
             if (!$image) {
                 break;
             }
             $creator = $image->getCreator();
             if ($image->get('image_type') == 2 && $creator['id'] != $user_id) {
                 $user_valid = false;
             }
             break;
         case 'articles':
             $article = Document::find('Article', $document_id, array('article_type'));
             if ($article->get('article_type') == 2 && !Association::find($user_id, $document_id, 'uc')) {
                 $user_valid = false;
             }
             break;
         default:
             break;
     }
     if (!$user_valid && !$user->hasCredential('moderator') || !$request->hasFiles()) {
         return false;
     }
     return true;
 }
 /**
  * filter for people who have the right to edit current document (linked people for outings, original editor for articles ....)
  * overrides the one in parent class. Triggered upon existing document editing.
  */
 protected function filterAuthorizedPeople($id)
 {
     $article = $this->document;
     // for an unknow reason, we have to double here this protection, which already exists at "document" level
     if ($article->get('is_protected') == true) {
         $referer = $this->getRequest()->getReferer();
         $this->setErrorAndRedirect('You cannot edit a protected document', $referer);
     }
     if ($article && ($type = $article->get('article_type') == 2)) {
         // personal article
         // these articles are only editable by associated authors + moderators
         $user = $this->getUser();
         $a = Association::find($user->getId(), $id, 'uc');
         // user-article
         if (!$a && !$user->hasCredential('moderator')) {
             $referer = $this->getRequest()->getReferer();
             $this->setErrorAndRedirect('You do not have the rights to edit this article', $referer);
         }
     }
 }
 public static function extractHighest($objects_array)
 {
     $highest_elevation = 0;
     foreach ($objects_array as $object) {
         // find highest
         // if elevations are equals, we need one extra request to check
         // whether $object os a parent of $highest object (should be a rare case)
         if ($object['elevation'] > $highest_elevation || $object['elevation'] == $highest_elevation && Association::find($object['id'], $highest_object['id'], 'ss', true)) {
             $highest_elevation = $object['elevation'];
             $highest_object = $object;
         } elseif ($highest_elevation == 0) {
             $highest_object = $object;
         }
     }
     return $highest_object;
 }