Esempio n. 1
0
 /** refresh geoassociations of the route and 'sub' outings */
 public function executeRefreshgeoassociations()
 {
     $referer = $this->getRequest()->getReferer();
     $id = $this->getRequestParameter('id');
     // check if user is moderator: done in apps/frontend/config/security.yml
     $document = Document::find($this->model_class, $id, array('geom'));
     if (!$document) {
         $this->setErrorAndRedirect('Document does not exist', $referer);
     }
     if (!$document->geom) {
         $this->setErrorAndRedirect('Cannot refresh route geoassociations for routes without geom', $referer);
     }
     $nb_created = gisQuery::createGeoAssociations($id, true, true);
     c2cTools::log("created {$nb_created} geo associations");
     $this->refreshGeoAssociations($id);
     $this->clearCache('routes', $id, false, 'view');
     $this->setNoticeAndRedirect('Geoassociations refreshed', "@document_by_id?module=routes&id={$id}");
 }
Esempio n. 2
0
 /**
  * Executes edit action.
  */
 public function executeEdit()
 {
     // populate objects for form display depending on what we are doing (creating, editing)
     $this->setEditFormInformation();
     // All modules will use the same template
     $this->setTemplate('../../documents/templates/edit');
     $document = $this->document;
     $module_name = $this->getModuleName();
     $this->document_name = $document->get('name');
     // Culture (lang) is automatically defined in Hydrate,
     // redefined in the model.
     if ($this->getRequest()->getMethod() == sfRequest::POST) {
         $lang = $this->getRequestParameter('lang');
         $user_id = $this->getUser()->getId();
         $is_minor = $this->getRequestParameter('rev_is_minor', false);
         $message = $this->getRequestParameter('rev_comment');
         $document->setCulture($lang);
         $old_lon = $document->get('lon');
         $old_lat = $document->get('lat');
         $this->setDataFields($document);
         // upload potential GPX file to server and set WKT field
         // or upload a new version of an image
         $request = $this->getRequest();
         if ($request->hasFiles()) {
             c2cTools::log('request has files');
             if ($request->getFileName('image_new_version') && $module_name == 'images') {
                 c2cTools::log('new image uploaded');
                 $base_path = sfConfig::get('sf_upload_dir') . DIRECTORY_SEPARATOR;
                 $temp_dir = $base_path . sfConfig::get('app_images_temp_directory_name');
                 $upload_dir = $base_path . sfConfig::get('app_images_directory_name');
                 $filename = $request->getFiles();
                 $unique_filename = c2cTools::generateUniqueName();
                 $file_ext = Images::detectExtension($filename['image_new_version']['tmp_name']);
                 // upload file in a temporary folder
                 $new_location = $temp_dir . DIRECTORY_SEPARATOR . $unique_filename . $file_ext;
                 sfLoader::loadHelpers(array('General'));
                 $redir_route = '@document_by_id_lang_slug?module=' . $module_name . '&id=' . $this->document->get('id') . '&lang=' . $this->document->getCulture() . '&slug=' . get_slug($this->document);
                 if (!$request->moveFile('image_new_version', $new_location)) {
                     return $this->setErrorAndRedirect('Failed moving uploaded file', $redir_route);
                 }
                 if ($file_ext == '.svg') {
                     if (!SVG::rasterize($temp_dir . DIRECTORY_SEPARATOR, $unique_filename, $file_ext)) {
                         return $this->setErrorAndRedirect('Failed rasterizing svg file', $redir_route);
                     }
                     $document->set('has_svg', true);
                 } else {
                     $document->set('has_svg', false);
                 }
                 // generate thumbnails (ie. resized images: "BI"/"SI")
                 Images::generateThumbnails($unique_filename, $file_ext, $temp_dir);
                 // move to uploaded images directory
                 if (!Images::moveAll($unique_filename . $file_ext, $temp_dir, $upload_dir)) {
                     return $this->setErrorAndRedirect('image dir unavailable', $redir_route);
                 }
                 // update filename and image properties
                 $document->set('filename', $unique_filename . $file_ext);
                 $size = getimagesize($upload_dir . DIRECTORY_SEPARATOR . $unique_filename . $file_ext);
                 if ($size) {
                     $document->set('width', $size[0]);
                     $document->set('height', $size[1]);
                 }
                 $document->set('file_size', filesize($upload_dir . DIRECTORY_SEPARATOR . $unique_filename . $file_ext));
                 // populate with new exif data, if any...
                 $document->populateWithExifDataFrom($upload_dir . DIRECTORY_SEPARATOR . $unique_filename . $file_ext);
             }
             if ($request->getFileName('gps_data') && in_array($module_name, array('routes', 'outings'))) {
                 // it is necessary to preserve both tests nested.
                 if ($wkt = $this->getWktFromFileUpload($request)) {
                     c2cTools::log('wkt extracted');
                     $document->set('geom_wkt', $wkt);
                     // NB: these fields exist in both objects for which a file upload is possible (outings, routes)
                     $_a = ParseGeo::getCumulatedHeightDiffFromWkt($wkt);
                     if (!$document->get('height_diff_up')) {
                         $document->set('height_diff_up', $_a['up']);
                         c2cTools::log('height diff up set from wkt : ' . $_a['up']);
                     }
                     if (!$document->get('height_diff_down')) {
                         $document->set('height_diff_down', $_a['down']);
                         c2cTools::log('height diff down set from wkt : ' . $_a['down']);
                     }
                     $message = '[geodata] ' . (!$message ? "Edit with geometry upload" : $message);
                 } else {
                     $this->getRequest()->setError('gps_data', 'invalid gpx file');
                     return false;
                 }
             }
         }
         if (count($this->document->getModified()) == 0 && count($this->document->getCurrentI18nObject()->getModified()) == 0) {
             // no change of the document was detected
             // => redirects to the document without saving anything
             $this->redirectToView();
             return;
         }
         // we prevent here concurrent edition :
         // fake data so that second test always fails on summit creation (and when document is an archive) :
         $rev_when_edition_begun = 1;
         $current_rev = 0;
         // test if id exists (summit update) before checking concurrent edition
         // and if this is not an archive (editing an old document to reverse wrong changes)
         // (because only useful for document update) :
         if (($id = $this->getRequestParameter('id')) && !$this->getRequestParameter('editing_archive')) {
             $rev_when_edition_begun = $this->getRequestParameter('revision');
             $current_rev = $document->getVersion();
         }
         c2cTools::log("Document {$id} in {$lang} : rev when edition begun : {$rev_when_edition_begun} - current rev : {$current_rev}");
         if ($rev_when_edition_begun < $current_rev) {
             c2cTools::log("Document {$id} in {$lang} has been concurrently saved. {$rev_when_edition_begun} < {$current_rev}");
             // document has been saved by someone else during edition
             // we present datas entered in the same form
             $this->document = $document;
             // and we launch a preview with the document in its true current state:
             $this->concurrent_edition = true;
             // if the current_document variable is available in the edit template, we display the preview of it.
         } else {
             $message = !$message ? "Edit in {$lang}" : $message;
             // if document has a geometry, compute and create associations with ranges, depts, countries.
             // nb: association is performed upon document creation with initial geometry
             // OR when the centroid (lon, lat) has moved during an update.
             $needs_geom_association = isset($wkt) || $document->get('lon') != $old_lon && $document->get('lon') != null || $document->get('lat') != $old_lat && $document->get('lat') != null;
             // geom centroid has moved
             $document->doSaveWithMetadata($user_id, $is_minor, $message);
             $this->success = true;
             // means that child class can redirect to document view after other operations if needed (eg: associations).
             $this->document = $document;
             $id = $document->get('id');
             if ($needs_geom_association) {
                 c2cTools::log('executeEdit: needs_geom_association');
                 // we create new associations :
                 //  (and delete old associations before creating the new ones)
                 //  (and do not create outings-maps associations)
                 $nb_created = gisQuery::createGeoAssociations($id, true, $module_name != 'outings');
                 c2cTools::log("created {$nb_created} geo associations");
                 // if summit or site coordinates have moved (hence $needs_geom_association = true),
                 // refresh geo-associations of associated routes (from summits) and outings (from routes or sites)
                 $this->refreshGeoAssociations($id);
             }
             // we clear views, histories, diffs of this doc + filter and list, in every language (content+interface):
             $this->clearCache($module_name, $id);
             // we clear views of the associated docs in every language (content+interface):
             // find all associated docs
             // 'users' module is excuded because a change of a user page have no visibility in associated docs, then it is not necessary to clear the cache of all associated outings
             if ($module_name != 'users') {
                 $associated_docs = Association::findAllAssociatedDocs($id, array('id', 'module'));
                 $ids = array();
                 foreach ($associated_docs as $doc) {
                     $doc_id = $doc['id'];
                     $doc_module = $doc['module'];
                     // clear their view cache
                     $this->clearCache($doc_module, $doc_id, false, 'view');
                     if ($module_name == 'outings' && in_array($doc_module, array('routes', 'sites')) || $module_name == 'routes' && in_array($doc_module, array('summits', 'parkings'))) {
                         $ids[] = $doc_id;
                     }
                 }
                 if ($module_name == 'outings') {
                     $associated_docs = Association::findAllAssociatedDocs($ids, array('id', 'module'), array('sr', 'hr', 'pr', 'rr', 'pt', 'ht'));
                     $ids = array();
                     foreach ($associated_docs as $doc) {
                         $doc_id = $doc['id'];
                         $doc_module = $doc['module'];
                         // clear their view cache
                         $this->clearCache($doc_module, $doc_id, false, 'view');
                         if (in_array($doc_module, array('summits', 'parkings', 'sites'))) {
                             $ids[] = $doc_id;
                         }
                     }
                     if (count($ids)) {
                         $associated_docs = Association::findMainAssociatedDocs($ids, array('id', 'module'), array('ss', 'pp', 'tt'));
                         foreach ($associated_docs as $doc) {
                             // clear their view cache
                             $this->clearCache($doc['module'], $doc['id'], false, 'view');
                         }
                     }
                 } elseif ($module_name == 'routes') {
                     $associated_docs = Association::findMainAssociatedDocs($ids, array('id', 'module'), array('ss', 'pp'));
                     foreach ($associated_docs as $doc) {
                         // clear their view cache
                         $this->clearCache($doc['module'], $doc['id'], false, 'view');
                     }
                 }
             }
             // saves new document id in a "pseudo id" cookie to retrieve it if user resubmits original form
             if ($this->new_document && $this->pseudo_id) {
                 $this->getResponse()->setCookie($this->pseudo_id, $id);
             }
         }
         // Go through simple heuristics to check for potential vandalism
         Vandalism::check($this->document);
     } else {
         // We display edit form. Retrieve nb comments
         $this->nb_comments = $this->new_document ? 0 : PunbbComm::retrieveNbComments($document->get('id') . '_' . $document->getCulture());
     }
     // module specific actions
     $this->endEdit();
 }
<?php

/**
 * Updates geo associations of documents contained in parameter areas.
 */
define('SF_ROOT_DIR', realpath(dirname(__FILE__) . '/..'));
define('SF_APP', 'frontend');
define('SF_ENVIRONMENT', 'dev');
define('SF_DEBUG', true);
require_once SF_ROOT_DIR . DIRECTORY_SEPARATOR . 'apps' . DIRECTORY_SEPARATOR . SF_APP . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . 'config.php';
// needed for doctrine connection to work
sfContext::getInstance();
// ids of areas containing objects of whom geoassociations must be updated:
$areas_ids = array(369, 379);
$i = 0;
foreach ($areas_ids as $id) {
    // find all doc associated to current area
    $associated_docs = GeoAssociation::findAllAssociations($id, null, 'linked');
    foreach ($associated_docs as $doc) {
        $doc_id = $doc->get('main_id');
        if (!($document = Document::find('Document', $doc_id, array('module')))) {
            continue;
        }
        // no maps are linked to outings, users and other maps
        $linkToMaps = !in_array($document->get('module'), array('outings', 'users', 'maps'));
        gisQuery::createGeoAssociations($doc_id, true, $linkToMaps);
        // TODO: handle "inherited" geo associations such as those of routes and outings
        $i++;
    }
}
echo "{$i} documents updated\n";
Esempio n. 4
0
 /** summits: refresh geo associations of summit, 'sub' routes and outings */
 public function updateGeoAssociations($id)
 {
     $referer = $this->getRequest()->getReferer();
     $this->document = Document::find($this->model_class, $id, array('summit_type'));
     if (!$this->document) {
         $this->setErrorAndRedirect('Document does not exist', $referer);
     }
     $nb_created = gisQuery::createGeoAssociations($id, true, true);
     c2cTools::log("created {$nb_created} geo associations");
     $this->refreshGeoAssociations($id);
     $this->clearCache('summits', $id, false, 'view');
     $this->setNoticeAndRedirect('Geoassociations refreshed', "@document_by_id?module=summits&id={$id}");
 }
Esempio n. 5
0
 /**
  * Executes easy upload action
  * Due to a limitation in flash... only the name of the file is usable
  * so other informations are sent by reference...
  */
 public function executeUpload()
 {
     $document_id = $this->getRequestParameter('document_id');
     $mod = $this->getRequestParameter('mod');
     $redir_route = "@document_by_id?module={$mod}&id={$document_id}";
     $request = $this->getRequest();
     if ($request->getMethod() == sfRequest::POST) {
         // check if user has the rights to upload images to the document
         $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')) {
             return $this->setErrorAndRedirect('Operation not allowed', $redir_route);
         }
         c2cTools::log('uploading files');
         $temp_dir = sfConfig::get('sf_upload_dir') . DIRECTORY_SEPARATOR . sfConfig::get('app_images_temp_directory_name') . DIRECTORY_SEPARATOR;
         if (!is_dir($temp_dir) || !is_writable($temp_dir)) {
             return $this->setErrorAndRedirect('image dir unavailable', $redir_route);
         }
         $uploaded_files = $request->getFiles();
         $uploaded_files = $uploaded_files['image_file'];
         $images_names = $this->getRequestParameter('name');
         $images_categories = $this->hasRequestParameter('categories') ? $this->getRequestParameter('categories') : array();
         $images_types = $this->getRequestParameter('image_type');
         // Note: sfWebRequest::getFile...() methods cannot be used directy since uploaded files
         // are transmitted in a image[] POST var that does not fit with those methods.
         foreach ($uploaded_files['tmp_name'] as $key => $filename) {
             $unique_filename = c2cTools::generateUniqueName();
             $file_ext = Images::detectExtension($filename);
             c2cTools::log("processing file {$unique_filename}");
             // upload file in a temporary folder
             $new_location = $temp_dir . $unique_filename . $file_ext;
             c2cTools::log("moving file to {$new_location}");
             if (!move_uploaded_file($filename, $new_location)) {
                 return $this->setErrorAndRedirect('Failed moving uploaded file', $redir_route);
             }
             // svg
             if ($file_ext == '.svg') {
                 if (!SVG::rasterize($temp_dir, $unique_filename, $file_ext)) {
                     return $this->setErrorAndRedirect('Failed rasterizing svg file', $redir_route);
                 }
             }
             // if jpg, check if we need orientation changes
             if ($file_ext == '.jpg') {
                 Images::correctOrientation("{$temp_dir}{$unique_filename}{$file_ext}");
             }
             c2cTools::log('resizing image');
             // generate thumbnails (ie. resized images: "BI"/"SI")
             Images::generateThumbnails($unique_filename, $file_ext, $temp_dir);
             // retrieve image caption (name)
             $name = array_key_exists($key, $images_names) ? $images_names[$key] : $this->__('Give me a name');
             // save image in DB and move temp files in the main dir
             c2cTools::log('saving image');
             $activities = array();
             $document = Document::find('Document', $document_id, array('id', 'module'));
             if (!$document) {
                 return 0;
             }
             $model = c2cTools::module2model($document->get('module'));
             if (in_array($model, array('Outing', 'Article', 'Book', 'Hut', 'Image', 'Route'))) {
                 $document = Document::find($model, $document_id, array('activities'));
                 $activities = $document->get('activities');
             } elseif ($model == 'Site') {
                 $activities = array(4);
                 // rock_climbing for sites by default
             }
             $image_type = $images_types[$key];
             $categories = array_key_exists($key, $images_categories) ? $images_categories[$key] : array();
             $image_id = Image::customSave($name, $unique_filename . $file_ext, $document_id, $user_id, $model, $activities, $categories, $image_type);
             $nb_created = gisQuery::createGeoAssociations($image_id, false);
             c2cTools::log("created {$nb_created} geo associations for image {$image_id}");
             // TODO: handle errors with thumbnails generation and data saving?
         }
         // remove cache of calling page
         $this->clearCache($mod, $document_id, false, 'view');
         // a new image has been uploaded, clear cache for images lists and whatsnew
         $this->clearCache('images', 0, true);
         return $this->setNoticeAndRedirect('image successfully uploaded', $redir_route . '#images');
     } else {
         switch ($mod) {
             case 'articles':
                 // default license depends on the article type
                 $article = Document::find('Article', $document_id);
                 $this->default_license = $article->get('article_type');
                 break;
             case 'books':
                 $this->default_license = 1;
                 break;
             case 'huts':
                 $this->default_license = 1;
                 break;
             case 'images':
                 // default license is that of associated image
                 $image = Document::find('Image', $document_id);
                 $this->default_license = $image->get('license');
                 break;
             case 'outings':
                 $this->default_license = 2;
                 break;
             case 'parkings':
                 $this->default_license = 1;
                 break;
             case 'routes':
                 $this->default_license = 1;
                 break;
             case 'sites':
                 $this->default_license = 1;
                 break;
             case 'summits':
                 $this->default_license = 1;
                 break;
             case 'products':
                 $this->default_license = 1;
                 break;
             case 'users':
                 $this->default_license = 2;
                 break;
             default:
                 $this->default_license = 2;
         }
     }
     // display form
 }