PageRenderTime 35ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/locations/edit.php

https://github.com/yacs/yacs
PHP | 341 lines | 176 code | 66 blank | 99 comment | 41 complexity | 81aef80afecf4051347aea293eb33e31 MD5 | raw file
  1. <?php
  2. /**
  3. * set a new location or update an existing one
  4. *
  5. * A button-based editor is used for the description field.
  6. * It's aiming to introduce most common [link=codes]codes/[/link] supported by YACS.
  7. *
  8. * See either [link=Address Map Coordinate (Lat/Long) Finder]http://www.batchgeocode.com/lookup/[/link]
  9. * or [link=Free Geocoding Service for 22 Countries]http://www.travelgis.com/geocode/Default.aspx[/link]
  10. * for more information.
  11. *
  12. * @link http://geotags.com/ GeoTags Search Engine
  13. * @link http://www.travelgis.com/geocode/Default.aspx Free Geocoding Service for 22 Countries
  14. *
  15. * This script attempts to validate the new or updated article description against a standard PHP XML parser.
  16. * The objective is to spot malformed or unordered HTML and XHTML tags. No more, no less.
  17. *
  18. * Restrictions apply on this page:
  19. * - anonymous (not-logged) surfer are invited to register to be able to post new locations
  20. * - members can post new locations, and modify their locations afterwards
  21. * - associates and editors can do what they want
  22. *
  23. * Accepted calls:
  24. * - edit.php?anchor=&lt;type&gt;:&lt;id&gt; add a new location for the anchor
  25. * - edit.php/&lt;id&gt; modify an existing location
  26. * - edit.php?id=&lt;id&gt; modify an existing location
  27. *
  28. * If the anchor for this item specifies a specific skin (option keyword '[code]skin_xyz[/code]'),
  29. * or a specific variant (option keyword '[code]variant_xyz[/code]'), they are used instead default values.
  30. *
  31. * @author Bernard Paques
  32. * @author Vincent No&euml;l
  33. * @author GnapZ
  34. * @author Christophe Battarel [email]christophe.battarel@altairis.fr[/email]
  35. * @tester Pat
  36. * @reference
  37. * @license http://www.gnu.org/copyleft/lesser.txt GNU Lesser General Public License
  38. */
  39. // common definitions and initial processing
  40. include_once '../shared/global.php';
  41. include_once 'locations.php';
  42. // look for the id
  43. $id = NULL;
  44. if(isset($_REQUEST['id']))
  45. $id = $_REQUEST['id'];
  46. elseif(isset($context['arguments'][0]) && !isset($context['arguments'][1]))
  47. $id = $context['arguments'][0];
  48. $id = strip_tags($id);
  49. // get the item from the database
  50. $item = Locations::get($id);
  51. // look for the target anchor on item creation
  52. $target_anchor = NULL;
  53. if(isset($_REQUEST['anchor']))
  54. $target_anchor = $_REQUEST['anchor'];
  55. elseif(isset($context['arguments'][1]))
  56. $target_anchor = $context['arguments'][0].':'.$context['arguments'][1];
  57. $target_anchor = strip_tags($target_anchor);
  58. // get the related anchor, if any
  59. $anchor = NULL;
  60. if(isset($item['anchor']))
  61. $anchor = Anchors::get($item['anchor']);
  62. elseif($target_anchor)
  63. $anchor = Anchors::get($target_anchor);
  64. // do not always show the edition form
  65. $with_form = FALSE;
  66. // load the skin, maybe with a variant
  67. load_skin('locations', $anchor);
  68. // do not index this page
  69. $context->sif('robots','noindex');
  70. // the path to this page
  71. if(is_object($anchor) && $anchor->is_viewable())
  72. $context['path_bar'] = $anchor->get_path_bar();
  73. else
  74. $context['path_bar'] = array( 'locations/' => i18n::s('Locations') );
  75. // the title of the page
  76. if(isset($item['id']))
  77. $context['page_title'] = i18n::s('Edit a location');
  78. else
  79. $context['page_title'] = i18n::s('Add a location');
  80. // stop crawlers
  81. if(Surfer::is_crawler()) {
  82. Safe::header('Status: 401 Unauthorized', TRUE, 401);
  83. Logger::error(i18n::s('You are not allowed to perform this operation.'));
  84. // anonymous users are invited to log in or to register
  85. } elseif(!Surfer::is_logged())
  86. Safe::redirect($context['url_to_home'].$context['url_to_root'].'users/login.php?url='.urlencode('locations/edit.php?id='.$id.'&anchor='.$_REQUEST['anchor']));
  87. // anyone can modify a location he/she posted previously; associates and editors can modify everything
  88. elseif(isset($item['id']) && ($item['edit_id'] != Surfer::get_id())
  89. && !Surfer::is_associate() && is_object($anchor) && !$anchor->is_assigned()) {
  90. Safe::header('Status: 401 Unauthorized', TRUE, 401);
  91. Logger::error(i18n::s('You are not allowed to perform this operation.'));
  92. // an anchor is mandatory
  93. } elseif(!is_object($anchor)) {
  94. Safe::header('Status: 404 Not Found', TRUE, 404);
  95. Logger::error(i18n::s('No anchor has been found.'));
  96. // maybe posts are not allowed here
  97. } elseif(!isset($item['id']) && is_object($anchor) && $anchor->has_option('locked') && !Surfer::is_empowered()) {
  98. Safe::header('Status: 401 Unauthorized', TRUE, 401);
  99. Logger::error(i18n::s('This page has been locked.'));
  100. // an error occured
  101. } elseif(count($context['error'])) {
  102. $item = $_REQUEST;
  103. $with_form = TRUE;
  104. // process uploaded data
  105. } elseif(isset($_SERVER['REQUEST_METHOD']) && ($_SERVER['REQUEST_METHOD'] == 'POST')) {
  106. // the follow-up page
  107. $next = $context['url_to_home'].$context['url_to_root'].$anchor->get_url();
  108. // display the form on error
  109. if(!$_REQUEST['id'] = Locations::post($_REQUEST)) {
  110. $item = $_REQUEST;
  111. $with_form = TRUE;
  112. // reward the poster for new posts
  113. } elseif(!isset($item['id'])) {
  114. // increment the post counter of the surfer
  115. Users::increment_posts(Surfer::get_id());
  116. // change page title
  117. $context['page_title'] = i18n::s('Thank you for your contribution');
  118. // show location attributes
  119. $attributes = array();
  120. if($_REQUEST['geo_place_name'])
  121. $attributes[] = $_REQUEST['geo_place_name'];
  122. if($_REQUEST['geo_position'])
  123. $attributes[] = $_REQUEST['geo_position'];
  124. if(is_array($attributes))
  125. $context['text'] .= '<p>'.implode(BR, $attributes)."</p>\n";
  126. // the action
  127. $context['text'] .= '<p>'.i18n::s('The location has been appended to the page.').'</p>';
  128. // touch the related anchor
  129. $anchor->touch('location:create', $_REQUEST['id'], isset($_REQUEST['silent']) && ($_REQUEST['silent'] == 'Y'));
  130. // clear cache
  131. Locations::clear($_REQUEST);
  132. // list persons that have been notified
  133. $context['text'] .= Mailer::build_recipients($anchor->get_reference());
  134. // follow-up commands
  135. $follow_up = i18n::s('What do you want to do now?');
  136. $menu = array();
  137. $menu = array_merge($menu, array($anchor->get_url() => i18n::s('View the page')));
  138. $menu = array_merge($menu, array($anchor->get_url('edit') => i18n::s('Edit the page')));
  139. $follow_up .= Skin::build_list($menu, 'menu_bar');
  140. $context['text'] .= Skin::build_block($follow_up, 'bottom');
  141. // log the submission by a non-associate
  142. if(!Surfer::is_associate() && is_object($anchor)) {
  143. $label = sprintf(i18n::c('New location in %s'), strip_tags($anchor->get_title()));
  144. $link = $context['url_to_home'].$context['url_to_root'].Locations::get_url($_REQUEST['id']);
  145. $description = $_REQUEST['geo_place_name']."\n"
  146. .sprintf(i18n::c('at %s'), '<a href="'.$link.'">'.$link.'</a>');
  147. Logger::notify('locations/edit.php: '.$label, $description);
  148. }
  149. // update of an existing location
  150. } else {
  151. // increment the post counter of the surfer
  152. Users::increment_posts(Surfer::get_id());
  153. // touch the related anchor
  154. $anchor->touch('location:update', $_REQUEST['id'], isset($_REQUEST['silent']) && ($_REQUEST['silent'] == 'Y'));
  155. // clear cache
  156. Locations::clear($_REQUEST);
  157. // forward to the view page
  158. Safe::redirect($context['url_to_home'].$context['url_to_root'].Locations::get_url($_REQUEST['id']));
  159. }
  160. // display the form on GET
  161. } else
  162. $with_form = TRUE;
  163. // display the form
  164. if($with_form) {
  165. // reference the anchor page
  166. if(is_object($anchor) && $anchor->is_viewable())
  167. $context['text'] .= '<p>'.sprintf(i18n::s('On page %s'), Skin::build_link($anchor->get_url(), $anchor->get_title()))."</p>\n";
  168. // the form to edit an location
  169. $context['text'] .= '<form method="post" action="'.$context['script_url'].'" onsubmit="return validateDocumentPost(this)" id="main_form" name="main_form"><div>';
  170. // form fields
  171. $fields = array();
  172. // display info on current version
  173. if(isset($item['id'])) {
  174. // the last poster
  175. if(isset($item['edit_id']) && $item['edit_id']) {
  176. $text = Users::get_link($item['edit_name'], $item['edit_address'], $item['edit_id'])
  177. .' '.Skin::build_date($item['edit_date']);
  178. $fields[] = array(i18n::s('Posted by'), $text);
  179. }
  180. }
  181. // geo place name
  182. $label = i18n::s('Place name');
  183. $input = '<input type="text" name="geo_place_name" id="geo_place_name" size="40" value="'.encode_field($item['geo_place_name']).'" />';
  184. // geocoding based on Google service
  185. if(isset($context['google_api_key']) && $context['google_api_key']) {
  186. // encode on click
  187. $input .= '<button type="button" id="encode" onclick="lookupAddress($(\'#geo_place_name\').val()); return false;">'.encode_field(i18n::s('Encode this address')).'</button>'."\n";
  188. Page::defer_script("http://maps.google.com/maps?file=api&amp;v=3&amp;key=".$context['google_api_key']);
  189. Page::insert_script(
  190. 'var geocoder = null;'."\n"
  191. .'function lookupAddress(address) {'."\n"
  192. .' if(!geocoder) {'."\n"
  193. .' geocoder = new google.maps.Geocoder();'."\n"
  194. .' }'."\n"
  195. .' if(geocoder) {'."\n"
  196. .' geocoder.geocode( { "address":container.geo_place_name.value},'."\n"
  197. .' function(point,status) {'."\n"
  198. .' if (!point) {'."\n"
  199. .' alert("'.i18n::s('This address has not been found').'");'."\n"
  200. .' } else {'."\n"
  201. .' $(\'#geo_position\').val( point[0].geometry.location.lat() + ", " + point[0].geometry.location.lng() );'."\n"
  202. .' alert("'.i18n::s('This address has been encoded as').'\n" + point[0].geometry.location.lat() + ", " + point[0].geometry.location.lat());'."\n"
  203. .' }'."\n"
  204. .' }'."\n"
  205. .' )'."\n"
  206. .' }'."\n"
  207. .'}'."\n"
  208. );
  209. }
  210. $hint = i18n::s('Street address, city, country');
  211. $fields[] = array($label, $input, $hint);
  212. // geo location
  213. $label = i18n::s('Coordinates');
  214. $input = '<input type="text" id="geo_position" name="geo_position" size="40" value="'.encode_field($item['geo_position']).'" />';
  215. $hint = i18n::s('Latitude, Longitude -- west longitudes and south latitudes are negative');
  216. $fields[] = array($label, $input, $hint);
  217. // geo country
  218. $label = i18n::s('Country');
  219. $input = '<input type="text" name="geo_country" size="40" value="'.encode_field($item['geo_country']).'" />';
  220. $hint = i18n::s('For regional positioning');
  221. $fields[] = array($label, $input, $hint);
  222. // the description
  223. $label = i18n::s('Description');
  224. // use the editor if possible
  225. $input = Surfer::get_editor('description', $item['description']);
  226. $fields[] = array($label, $input);
  227. // build the form
  228. $context['text'] .= Skin::build_form($fields);
  229. $fields = array();
  230. // associates may decide to not stamp changes -- complex command
  231. if(Surfer::is_associate() && Surfer::has_all())
  232. $context['text'] .= '<p><input type="checkbox" name="silent" value="Y" /> '.i18n::s('Do not change modification date of the main page.').'</p>';
  233. // the submit button
  234. $context['text'] .= '<p>'.Skin::build_submit_button(i18n::s('Submit'), i18n::s('Press [s] to submit data'), 's').'</p>'."\n";
  235. // transmit the id as a hidden field
  236. if(isset($item['id']) && $item['id'])
  237. $context['text'] .= '<input type="hidden" name="id" value="'.$item['id'].'" />';
  238. // other hidden fields
  239. $context['text'] .= '<input type="hidden" name="anchor" value="'.$anchor->get_reference().'" />';
  240. // end of the form
  241. $context['text'] .= '</div></form>';
  242. // the script used for form handling at the browser
  243. Page::insert_script(
  244. // check that main fields are not empty
  245. ' func'.'tion validateDocumentPost(container) {'."\n"
  246. // geo_place_name is mandatory
  247. .' if(!container.geo_place_name.value) {'."\n"
  248. .' alert("'.i18n::s('You must give a name to this location.').'");'."\n"
  249. .' Yacs.stopWorking();'."\n"
  250. .' return false;'."\n"
  251. .' }'."\n"
  252. // geo_position is mandatory
  253. .' if(!container.geo_position.value) {'."\n"
  254. .' alert("'.i18n::s('Please type some geographical coordinates.').'");'."\n"
  255. .' Yacs.stopWorking();'."\n"
  256. .' return false;'."\n"
  257. .' }'."\n"
  258. // successful check
  259. .' return true;'."\n"
  260. .' }'."\n"
  261. // set the focus on first form field
  262. .'$("#geo_place_name").focus();'."\n"
  263. );
  264. // general help on this form
  265. $help = '<p>'.i18n::s('Latitude and longitude are numbers separated by a comma and spaces, for example: 47.98481,-71.42124.').'</p>'
  266. .i18n::s('To find coordinates of any emplacement you can visit following sites:').'<ul>'
  267. .'<li>'.Skin::build_link(i18n::s('http://www.batchgeocode.com/lookup/'), i18n::s('Address Map Coordinate (Lat/Long) Finder'), 'external').'</li>'
  268. .'<li>'.Skin::build_link(i18n::s('http://www.travelgis.com/geocode/Default.aspx'), i18n::s('Free Geocoding Service for 22 Countries'), 'external').'</li>'
  269. .'</ul>'
  270. .'<p>'.sprintf(i18n::s('%s and %s are available to enhance text rendering.'), Skin::build_link('codes/', i18n::s('YACS codes'), 'open'), Skin::build_link('smileys/', i18n::s('smileys'), 'open')).'</p>';
  271. $context['components']['boxes'] = Skin::build_box(i18n::s('Help'), $help, 'boxes', 'help');
  272. }
  273. // render the skin
  274. render_skin();
  275. ?>