GeoMashup
[ class tree: GeoMashup ] [ index: GeoMashup ] [ all elements ]

Source for file geo-mashup-ui-managers.php

Documentation is available at geo-mashup-ui-managers.php

  1. <?php
  2. /** 
  3.  * Geo Mashup "core" implementation of location management user interfaces.
  4.  *
  5.  * Theoretically, everything done here could be done in a separate plugin.
  6.  *
  7.  * @package GeoMashup
  8.  */
  9.  
  10. /**
  11.  * A base class for managing user interfaces for collecting and storing location.
  12.  *
  13.  * This could be extended to make the existing editor work for new objects in a separate plugin.
  14.  *
  15.  * @package GeoMashup
  16.  * @since 1.3
  17.  * @access public
  18.  */
  19.     /**
  20.      * Retrieve a single instaniated subclass by name.
  21.      *
  22.      * @since 1.3
  23.      *
  24.      * @param string $name The class name of the manager.
  25.      * @return GeoMashupUIManager The singleton object.
  26.      */
  27.     public static function &get_instance( $name ) {
  28.         static $instances = array();
  29.  
  30.         if ( ! isset( $instances[$name] ) ) {
  31.             $instances[$name] = new $name();
  32.         }
  33.         return $instances[$name];
  34.     }
  35.  
  36.     /**
  37.      * Queue UI styles to match the jQuery version.
  38.      * 
  39.      * @since 1.3
  40.      */
  41.     public function enqueue_jquery_styles() {
  42.         GeoMashup::register_style( 'jquery-smoothness', 'css/jquery-ui.1.7.smoothness.css', false, GEO_MASHUP_VERSION, 'screen' );
  43.         wp_enqueue_style( 'jquery-smoothness' );
  44.     }
  45.  
  46.     /**
  47.      * Queue styles and scripts for the location editor form.
  48.      *
  49.      * @since 1.3
  50.      */
  51.     public function enqueue_form_client_items() {
  52.         global $geo_mashup_options, $geo_mashup_custom;
  53.         
  54.         GeoMashup::register_style( 'geo-mashup-edit-form', 'css/location-editor.css', false, GEO_MASHUP_VERSION, 'screen' );
  55.         wp_enqueue_style( 'geo-mashup-edit-form' );
  56.  
  57.         GeoMashup::register_script( 'mxn', 'js/mxn/mxn.js', null, GEO_MASHUP_VERSION );
  58.         GeoMashup::register_script( 'mxn-core', 'js/mxn/mxn.core.js', array( 'mxn' ), GEO_MASHUP_VERSION );
  59.  
  60.         $map_api = $geo_mashup_options->get( 'overall', 'map_api' );
  61.         $geonames_username = $geo_mashup_options->get( 'overall', 'geonames_username' );
  62.         $ajax_nonce = wp_create_nonce('geo-mashup-ajax-edit');
  63.         $ajax_url = admin_url( 'admin-ajax.php' );
  64.         $geo_mashup_url_path = GEO_MASHUP_URL_PATH;
  65.         wp_localize_script( 'mxn-core', 'geo_mashup_location_editor_settings', compact( 'map_api', 'ajax_url', 'geo_mashup_url_path', 'geonames_username' ) );
  66.         $required_scripts = array( 'jquery');
  67.         if ( 'google' == $map_api ) {
  68.             wp_register_script( 'google-maps-2', 'http://maps.google.com/maps?file=api&amp;v=2&amp;sensor=false&amp;key=' . 
  69.                 $geo_mashup_options->get( 'overall', 'google_key' ) . '&amp;hl=' . GeoMashup::get_language_code() );
  70.             GeoMashup::register_script( 'mxn-google-2', 'js/mxn/mxn.google.core.js', array( 'mxn-core', 'google-maps-2' ), GEO_MASHUP_VERSION );
  71.             GeoMashup::register_script( 'mxn-google-2-gm', 'js/mxn/mxn.google.geo-mashup.js', array( 'mxn-google-2' ), GEO_MASHUP_VERSION );
  72.             $required_scripts[] = 'mxn-google-2-gm';
  73.         } else if ( 'googlev3' == $map_api ) {
  74.             wp_register_script( 'google-maps-3', 'http://maps.google.com/maps/api/js?sensor=false&amp;language=' . GeoMashup::get_language_code() );
  75.             GeoMashup::register_script( 'mxn-google-3', 'js/mxn/mxn.googlev3.core.js', array( 'mxn-core', 'google-maps-3' ), GEO_MASHUP_VERSION );
  76.             GeoMashup::register_script( 'mxn-google-3-gm', 'js/mxn/mxn.googlev3.geo-mashup.js', array( 'mxn-google-3' ), GEO_MASHUP_VERSION );
  77.             $required_scripts[] = 'mxn-google-3-gm';
  78.         } else if ( 'openlayers' == $map_api ) {
  79.             wp_register_script( 'openlayers', 'http://openlayers.org/api/OpenLayers.js', null, 'latest' );
  80.             wp_register_script( 'openstreetmap', 'http://www.openstreetmap.org/openlayers/OpenStreetMap.js', array( 'openlayers' ), 'latest' );
  81.             GeoMashup::register_script( 'mxn-openlayers', 'js/mxn/mxn.openlayers.core.js', array( 'mxn-core', 'openstreetmap' ), GEO_MASHUP_VERSION );
  82.             GeoMashup::register_script( 'mxn-openlayers-gm', 'js/mxn/mxn.openlayers.geo-mashup.js', array( 'mxn-openlayers' ), GEO_MASHUP_VERSION );
  83.             $required_scripts[] = 'mxn-openlayers-gm';
  84.         }
  85.  
  86.         GeoMashup::register_script( 'geo-mashup-location-editor', 'js/location-editor.js', $required_scripts, GEO_MASHUP_VERSION );
  87.         wp_enqueue_script( 'geo-mashup-location-editor' );
  88.  
  89.         GeoMashup::register_script( 'jquery-ui-datepicker', 'js/jquery-ui.1.7.3.datepicker.js', array( 'jquery', 'jquery-ui-core'), '1.7.3' );
  90.         wp_enqueue_script( 'jquery-ui-datepicker' );
  91.  
  92.         if ( isset( $geo_mashup_custom ) ) {
  93.             $custom_url = $geo_mashup_custom->file_url( 'location-editor.js' );
  94.             if ( ! empty( $custom_url ) ) {
  95.                 wp_enqueue_script( 'geo-mashup-location-editor-custom', $custom_url, array( 'geo-mashup-location-editor' ) );
  96.             }
  97.         }
  98.     }
  99.  
  100.     /**
  101.      * Determine the appropriate action from posted data.
  102.      * 
  103.      * @since 1.3
  104.      */
  105.     private function get_submit_action() {
  106.  
  107.         $action = null;
  108.  
  109.         if ( isset( $_POST['geo_mashup_add_location'] ) or isset( $_POST['geo_mashup_update_location'] ) ) {
  110.  
  111.             // Clients without javascript may need server side geocoding
  112.             if ( ! empty( $_POST['geo_mashup_search'] ) and isset( $_POST['geo_mashup_no_js'] ) and 'true' == $_POST['geo_mashup_no_js'] ) {
  113.  
  114.                 $action = 'geocode';
  115.  
  116.             } else {
  117.  
  118.                 $action = 'save';
  119.  
  120.             }
  121.  
  122.         } else if ( isset( $_POST['geo_mashup_changed'] ) and 'true' == $_POST['geo_mashup_changed'] and ! empty( $_POST['geo_mashup_location'] ) ) {
  123.  
  124.             // The geo mashup submit button wasn't used, but a change was made and the post saved
  125.             $action = 'save';
  126.                  
  127.         } else if ( isset( $_POST['geo_mashup_delete_location'] ) ) {
  128.  
  129.             $action = 'delete';
  130.  
  131.         } else if ( ! empty( $_POST['geo_mashup_location_id'] ) and empty( $_POST['geo_mashup_location'] ) ) {
  132.  
  133.             // There was a location, but it was cleared before this save
  134.             $action = 'delete';
  135.  
  136.         }
  137.         return $action;
  138.     }
  139.  
  140.     /**
  141.      * Save an object location from data posted by the location editor.
  142.      * 
  143.      * @since 1.3
  144.      * @uses GeoMashupDB::set_object_location()
  145.      * @uses GeoMashupDB::delete_location()
  146.      *
  147.      * @param string $object_name The name of the object being edited.
  148.      * @param string $object_id The ID of the object being edited.
  149.      * @return bool|WP_ErrorTrue or a WordPress error.
  150.      */
  151.     public function save_posted_object_location( $object_name, $object_id ) {
  152.  
  153.         // Check the nonce
  154.         if ( empty( $_POST['geo_mashup_nonce'] ) || !wp_verify_nonce( $_POST['geo_mashup_nonce'], 'geo-mashup-edit' ) ) {
  155.             return new WP_Error( 'invalid_request', __( 'Object location not saved - invalid request.', 'GeoMashup' ) );
  156.         }
  157.         
  158.         $action = $this->get_submit_action();
  159.  
  160.         if ( 'save' == $action or 'geocode' == $action ) {
  161.  
  162.             $date_string = $_POST['geo_mashup_date'] . ' ' . $_POST['geo_mashup_hour'] . ':' . 
  163.                 $_POST['geo_mashup_minute'] . ':00';
  164.             $geo_date = date( 'Y-m-d H:i:s', strtotime( $date_string ) );
  165.  
  166.             $post_location = array();
  167.             // If PHP has added slashes, WP will do it again before saving
  168.             $post_location['saved_name'] = stripslashes( $_POST['geo_mashup_location_name'] );
  169.  
  170.             if ( 'geocode' == $action ) {
  171.  
  172.                 $status = GeoMashupDB::geocode( $_POST['geo_mashup_search'], $post_location );
  173.                 if ( $status != 200 ) {
  174.                     $post_location = array();
  175.                 }
  176.  
  177.             } else {
  178.  
  179.                 if ( ! empty( $_POST['geo_mashup_select'] ) ) {
  180.                     $selected_items = explode( '|', $_POST['geo_mashup_select'] );
  181.                     $post_location = intval( $selected_items[0] );
  182.                 } else { 
  183.                     $post_location['id'] = $_POST['geo_mashup_location_id'];
  184.                     list( $lat, $lng ) = split( ',', $_POST['geo_mashup_location'] );
  185.                     $post_location['lat'] = trim( $lat );
  186.                     $post_location['lng'] = trim( $lng );
  187.                     $post_location['geoname'] = $_POST['geo_mashup_geoname'];
  188.                     $post_location['address'] = stripslashes( $_POST['geo_mashup_address'] );
  189.                     $post_location['postal_code'] = $_POST['geo_mashup_postal_code'];
  190.                     $post_location['country_code'] = $_POST['geo_mashup_country_code'];
  191.                     $post_location['admin_code'] = $_POST['geo_mashup_admin_code'];
  192.                     $post_location['sub_admin_code'] = $_POST['geo_mashup_sub_admin_code'];
  193.                     $post_location['locality_name'] = $_POST['geo_mashup_locality_name'];
  194.                 }
  195.             }
  196.             
  197.             if ( ! empty( $post_location ) ) {
  198.                 $error = GeoMashupDB::set_object_location( $object_name, $object_id, $post_location, true, $geo_date );
  199.                 if ( is_wp_error( $error ) ) 
  200.                     return $error;
  201.             }
  202.  
  203.         } else if ( 'delete' == $action ) {
  204.  
  205.             $error = GeoMashupDB::delete_object_location( $object_name, $object_id );
  206.             if ( is_wp_error( $error ) ) 
  207.                 return $error;
  208.  
  209.         }
  210.         // If geodata was manually updated but Geo Mashup location was not,
  211.         // they may be out of sync now. Allowing that for now.
  212.         return true;
  213.     }
  214. }
  215.  
  216. /**
  217.  * A manager for user location user interfaces.
  218.  *
  219.  * Singleton instantiated immediately.
  220.  *
  221.  * @package GeoMashup
  222.  * @since 1.3
  223.  * @access public
  224.  */
  225.     /**
  226.      * Get the single instance of this class.
  227.      * 
  228.      * @since 1.3
  229.      * @uses parent::get_instance()
  230.      *
  231.      * @return GeoMashupPostUIManager The instance.
  232.      */
  233.     public static function get_instance() {
  234.         return parent::get_instance( 'GeoMashupUserUIManager' );
  235.     }
  236.  
  237.     /**
  238.      * PHP5 Constructor
  239.      *
  240.      * @since 1.3
  241.      * @access private
  242.      */
  243.     public function __construct() {
  244.         // Global $geo_mashup_options is available, but a better pattern might
  245.         // be to wait until init to be sure
  246.         add_action( 'init', array( &$this, 'init' ) );
  247.     }
  248.  
  249.     /**
  250.      * Initialize for use in relevant requests.
  251.      *
  252.      * init {@link http://codex.wordpress.org/Plugin_API/Action_Reference action}
  253.      * called by WordPress.
  254.      * 
  255.      * @since 1.3
  256.      * @global array $geo_mashup_options 
  257.      * @global string $pagenow The WordPress-supplied requested filename.
  258.      * @uses apply_filters geo_mashup_load_user_editor Returns a boolean that loads the editor when true.
  259.      */
  260.     public function init() {
  261.         global $geo_mashup_options, $pagenow;
  262.  
  263.         // Enable this interface when the option is set and we're on a destination page
  264.         $enabled = is_admin() &&
  265.             $geo_mashup_options->get( 'overall', 'located_object_name', 'user' ) == 'true' &&
  266.             preg_match( '/(user-edit|user-new|profile).php/', $pagenow );
  267.         $enabled = apply_filters( 'geo_mashup_load_user_editor', $enabled );
  268.  
  269.         // If enabled, register all the interface elements
  270.         if ( $enabled ) { 
  271.  
  272.             // Form generation
  273.             add_action( 'show_user_profile', array( &$this, 'print_form' ) );
  274.             add_action( 'edit_user_profile', array( &$this, 'print_form' ) );
  275.             // MAYBEDO: add location to registration page?
  276.  
  277.             // Form processing
  278.             add_action( 'personal_options_update', array( &$this, 'save_user'));
  279.             add_action( 'edit_user_profile_update', array( &$this, 'save_user'));
  280.  
  281.             $this->enqueue_jquery_styles();
  282.             $this->enqueue_form_client_items();
  283.         }
  284.     }
  285.  
  286.     /**
  287.      * Print the user location editor form.
  288.      * 
  289.      * @since 1.3
  290.      * @uses edit-form.php
  291.      */
  292.     public function print_form() {
  293.         global $user_id;
  294.  
  295.         include_once( GEO_MASHUP_DIR_PATH . '/edit-form.php');
  296.         if ( isset( $_GET['user_id'] ) ) {
  297.             $object_id = $_GET['user_id'];
  298.         } else {
  299.             $object_id = $user_id;
  300.         }
  301.         echo '<h3>' . __( 'Location', 'GeoMashup' ) . '</h3>';
  302.         geo_mashup_edit_form( 'user', $object_id, get_class( $this ) );
  303.     }
  304.  
  305.     /**
  306.      * Save a posted user location.
  307.      * 
  308.      * @since 1.3
  309.      * @uses parent::save_posted_object_location()
  310.      *
  311.      * @param id $user_id 
  312.      * @return bool|WP_Error
  313.      */
  314.     public function save_posted_object_location( $user_id ) {
  315.         return parent::save_posted_object_location( 'user', $user_id );
  316.     }
  317.  
  318.     /**
  319.      * When a user is saved, also save any posted location.
  320.      *
  321.      * save_user {@link http://codex.wordpress.org/Plugin_API/Action_Reference action}
  322.      * called by WordPress.
  323.      * 
  324.      * @since 1.3
  325.      * @return bool|WP_Error
  326.      */
  327.     public function save_user() {
  328.         if ( empty( $_POST['user_id'] ) ) {
  329.             return false;
  330.         }
  331.  
  332.         $user_id = $_POST['user_id'];
  333.  
  334.         if ( !is_numeric( $user_id ) ) {
  335.             return $user_id;
  336.         }
  337.  
  338.         if ( !current_user_can( 'edit_user', $user_id ) ) {
  339.             return $user_id;
  340.         }
  341.  
  342.         return $this->save_posted_object_location( $user_id );
  343.     }
  344. }
  345.  
  346. // Instantiate
  347.  
  348. /**
  349.  * A manager for post/page location user interfaces.
  350.  *
  351.  * Singleton instantiated immediately.
  352.  *
  353.  * @package GeoMashup
  354.  * @since 1.3
  355.  * @access public
  356.  */
  357.     /**
  358.      * Location found in geo_mashup_save_location shortcode.
  359.      * 
  360.      * @since 1.3
  361.      * @var array 
  362.      */
  363.     private $inline_location;
  364.  
  365.     /**
  366.      * Get the single instance of this class.
  367.      * 
  368.      * @since 1.3
  369.      * @uses parent::get_instance()
  370.      *
  371.      * @return GeoMashupPostUIManager The instance.
  372.      */
  373.     public static function get_instance() {
  374.         return parent::get_instance( 'GeoMashupPostUIManager' );
  375.     }
  376.  
  377.     /**
  378.      * PHP5 Constructor
  379.      *
  380.      * @since 1.3
  381.      */
  382.     public function __construct() {
  383.         // Global $geo_mashup_options is available, but a better pattern might
  384.         // be to wait until init to be sure
  385.         add_action( 'init', array( &$this, 'init' ) );
  386.     }
  387.  
  388.     /**
  389.      * Initialize for use in relevant post editing requests.
  390.      *
  391.      * init {@link http://codex.wordpress.org/Plugin_API/Action_Reference action}
  392.      * called by WordPress.
  393.      * 
  394.      * @since 1.3
  395.      * @global array $geo_mashup_options 
  396.      * @global string $pagenow The WordPress-supplied requested filename.
  397.      * @uses apply_filters geo_mashup_load_location_editor Returns a boolean that loads the editor when true.
  398.      */
  399.     public function init() {
  400.         global $geo_mashup_options, $pagenow;
  401.  
  402.         // Uploadable geo content type expansion always enabled
  403.         add_filter( 'upload_mimes', array( &$this, 'upload_mimes' ) );
  404.  
  405.         // Queue inline location handlers - these could be used in nearly any request
  406.  
  407.         // Pre-save filter checks saved content for inline location tags
  408.         add_filter( 'content_save_pre', array( &$this, 'content_save_pre') );
  409.  
  410.         // Save post handles both inline and form processing
  411.         add_action( 'save_post', array( &$this, 'save_post'), 10, 2 );
  412.  
  413.         // Browser upload processing
  414.         add_filter( 'wp_handle_upload', array( &$this, 'wp_handle_upload' ) );
  415.  
  416.         // Enable front or back end ajax edits
  417.         add_action( 'wp_ajax_nopriv_geo_mashup_edit', array( 'GeoMashup', 'ajax_edit' ) );
  418.         add_action( 'wp_ajax_geo_mashup_edit', array( 'GeoMashup', 'ajax_edit' ) );
  419.  
  420.         // Form generation
  421.         add_action( 'admin_menu', array( &$this, 'admin_menu' ) );
  422.  
  423.         // Queue scripts later, when we can determine post type, front or back end
  424.         add_action( 'admin_enqueue_scripts', array( &$this, 'enqueue_scripts' ) );
  425.         add_action( 'wp_enqueue_scripts', array( &$this, 'enqueue_scripts' ) );
  426.  
  427.         if ( 'async-upload.php' === $pagenow ) {
  428.  
  429.             // Flash upload display
  430.             add_filter( 'media_meta', array( &$this, 'media_meta' ), 10, 2 );
  431.  
  432.         } else if ( 'upload.php' === $pagenow or 'media-upload.php' === $pagenow ) {
  433.  
  434.             // Browser upload display
  435.             add_action( 'admin_print_scripts', array( &$this, 'admin_print_scripts' ) );
  436.  
  437.         }
  438.  
  439.     }
  440.  
  441.     /**
  442.      * Queue scripts if the post type is enabled.
  443.      *
  444.      * Monitor for checking post type: http://core.trac.wordpress.org/ticket/14886
  445.      *
  446.      * @since 1.4
  447.      * @uses apply_filters geo_mashup_load_location_editor intended for enabling a front end interface
  448.      *
  449.      * @global array $geo_mashup_options 
  450.      * @global string $pagenow 
  451.      * @global object $post 
  452.      */
  453.     public function enqueue_scripts() {
  454.         global $geo_mashup_options, $pagenow, $post;
  455.  
  456.         // The location editor works only on posts
  457.         if ( empty( $post ) )
  458.             return null;
  459.  
  460.         $load_location_editor = (
  461.                 is_admin() and
  462.                 preg_match( '/(post|page)(-new|).php/', $pagenow ) and
  463.                 in_array( $post->post_type, $geo_mashup_options->get( 'overall', 'located_post_types' ) )
  464.                 );
  465.         $load_location_editor = apply_filters( 'geo_mashup_load_location_editor', $load_location_editor );
  466.  
  467.         // If we're on a post editing page, queue up the form interface elements
  468.         if ( $load_location_editor ) {
  469.  
  470.             $this->enqueue_jquery_styles();
  471.             $this->enqueue_form_client_items();
  472.  
  473.         } 
  474.     }
  475.  
  476.     /**
  477.      * Add a location meta box to the post editors.
  478.      * 
  479.      * admin_menu {@link http://codex.wordpress.org/Plugin_API/Action_Reference action}
  480.      * called by Wordpress.
  481.      *
  482.      * @since 1.3
  483.      */
  484.     public function admin_menu() {
  485.         global $geo_mashup_options;
  486.         // Not adding a menu, but at this stage add_meta_box is defined, so we can add the location form
  487.         foreach ( $geo_mashup_options->get( 'overall', 'located_post_types' ) as $post_type ) {
  488.             add_meta_box( 'geo_mashup_post_edit', __( 'Location', 'GeoMashup' ), array( &$this, 'print_form' ), $post_type, 'advanced' );
  489.         }
  490.     }
  491.  
  492.     /**
  493.      * Print the post editor form.
  494.      * 
  495.      * @since 1.3
  496.      * @uses edit-form.php
  497.      */
  498.     public function print_form() {
  499.         global $post_ID;
  500.  
  501.         include_once( GEO_MASHUP_DIR_PATH . '/edit-form.php');
  502.         geo_mashup_edit_form( 'post', $post_ID, get_class( $this ) );
  503.     }
  504.  
  505.     /**
  506.      * Save a posted post or page location.
  507.      * 
  508.      * @since 1.3
  509.      * @uses parent::save_posted_object_location()
  510.      *
  511.      * @param id $post_id 
  512.      * @return bool|WP_Error
  513.      */
  514.     public function save_posted_object_location( $post_id ) {
  515.         return parent::save_posted_object_location( 'post', $post_id );
  516.     }
  517.  
  518.     /**
  519.      * When a post is saved, save any posted location for it.
  520.      * 
  521.      * save_post {@link http://codex.wordpress.org/Plugin_API/Action_Reference action}
  522.      * called by WordPress.
  523.      *
  524.      * @since 1.3
  525.      * @uses GeoMashupDB::set_object_location()
  526.      *
  527.      * @param id $post_id 
  528.      * @param object $post 
  529.      * @return bool|WP_Error
  530.      */
  531.     public function save_post($post_id, $post) {
  532.         if ( 'revision' == $post->post_type ) {
  533.             return;
  534.         }
  535.  
  536.         // WP has already saved the post - allow location saving without added capability checks
  537.  
  538.         if ( !empty( $this->inline_location ) ) {
  539.             $geo_date = '';
  540.             if ( isset( $this->inline_location['geo_date'] ) ) {
  541.                 $geo_date = $this->inline_location['geo_date'];
  542.                 unset( $this->inline_location['geo_date'] );
  543.             }
  544.             $location_id = GeoMashupDB::set_object_location( 'post', $post_id, $this->inline_location, true, $geo_date );
  545.             if ( is_wp_error( $location_id ) ) {
  546.                 update_post_meta( $post_id, 'geo_mashup_save_location_error', $location_id->get_error_message() );
  547.             }
  548.             $this->inline_location = null;
  549.         }
  550.  
  551.         delete_transient( 'gm_uploaded_kml_url' );
  552.  
  553.         return $this->save_posted_object_location( $post_id );
  554.     }
  555.  
  556.     /**
  557.      * Extract inline save location shortcodes from post content before it is saved.
  558.      *
  559.      * content_save_pre {@link http://codex.wordpress.org/Plugin_API/Filter_Reference filter}
  560.      * called by Wordpress.
  561.      * 
  562.      * @since 1.3
  563.      */
  564.     public function content_save_pre( $content ) {
  565.         // Piggyback on the shortcode interface to find inline tags [geo_mashup_save_location ...] 
  566.         add_shortcode( 'geo_mashup_save_location', 'is_null' );
  567.         $pattern = get_shortcode_regex( );
  568.         return preg_replace_callback('/'.$pattern.'/s', array( &$this, 'replace_save_pre_shortcode' ), $content);
  569.     }
  570.  
  571.     /**
  572.      * Store the inline location from a save location shortcode before it is removed.
  573.      * 
  574.      * @since 1.3
  575.      *
  576.      * @param array $shortcode_match 
  577.      * @return The matched content, or an empty string if it was a save location shortcode.
  578.      */
  579.     public function replace_save_pre_shortcode( $shortcode_match ) {
  580.         $content = $shortcode_match[0];
  581.         $tag_index = array_search( 'geo_mashup_save_location',  $shortcode_match ); 
  582.         if ( $tag_index !== false ) {
  583.             // There is an inline location - save the attributes
  584.             $this->inline_location = shortcode_parse_atts( stripslashes( $shortcode_match[$tag_index+1] ) );
  585.  
  586.             // If lat and lng are missing, try to geocode based on address
  587.             $success = false;
  588.             if ( ( empty( $this->inline_location['lat'] ) or empty( $this->inline_location['lng'] ) ) and !empty( $this->inline_location['address'] ) ) {
  589.                 $query = $this->inline_location['address'];
  590.                 $this->inline_location = GeoMashupDB::blank_object_location( ARRAY_A );
  591.                 $success = GeoMashupDB::geocode( $query, $this->inline_location );
  592.                 if ( !$success ) {
  593.                     // Delay and try again
  594.                     sleep( 1 );
  595.                     $success = GeoMashupDB::geocode( $query, $this->inline_location );
  596.                 }
  597.             }
  598.  
  599.             if ( $success ) {
  600.                 // Remove the tag
  601.                 $content = '';
  602.             } else {
  603.                 $message = ( is_wp_error( GeoMashupDB::$geocode_error ) ? GeoMashupDB::$geocode_error->get_error_message() : __( 'Address not found - try making it less detailed', 'GeoMashup' ) );
  604.                 $content = str_replace( ']', ' geocoding_error="' . $message . '"]', $content );
  605.                 $this->inline_location = null;
  606.             }
  607.         } 
  608.         return $content;
  609.     }
  610.  
  611.     /**
  612.      * Add Flash-uploaded KML to the location editor map.
  613.      *
  614.      * media_meta {@link http://codex.wordpress.org/Plugin_API/Filter_Reference filter}
  615.      * called by WordPress.
  616.      * 
  617.      * @since 1.3
  618.      */
  619.     public function media_meta( $content, $post ) {
  620.         // Only chance to run some javascript after a flash upload?
  621.         if (strlen($post->guid) > 0) {
  622.             $content .= '<script type="text/javascript"> ' .
  623.                 'if (\'GeoMashupLocationEditor\' in parent) parent.GeoMashupLocationEditor.loadKml(\''.$post->guid.'\');' .
  624.                 '</script>';
  625.         }
  626.         return $content;
  627.     }
  628.  
  629.     /**
  630.      * Add Browser-uploaded KML to the location editor map.
  631.      *
  632.      * admin_print_scripts {@link http://codex.wordpress.org/Plugin_API/Action_Reference action}
  633.      * called by WordPress.
  634.      * 
  635.      * @since 1.3
  636.      */
  637.     public function admin_print_scripts( $not_used ) {
  638.         // Load any uploaded KML into the search map - only works with browser uploader
  639.         
  640.         // See if wp_upload_handler found uploaded KML
  641.         $kml_url = get_transient( 'gm_uploaded_kml_url' );
  642.         if (strlen($kml_url) > 0) {
  643.             // Load the KML in the location editor
  644.             echo '
  645.                 <script type="text/javascript"> 
  646.                     if (\'GeoMashupLocationEditor\' in parent) parent.GeoMashupLocationEditor.loadKml(\'' . $kml_url . '\');
  647.                 </script>';
  648.             delete_transient( 'gm_uploaded_kml_url' );
  649.         }
  650.     }
  651.  
  652.     /**
  653.      * Add geo mime types to allowable uploads.
  654.      * 
  655.      * upload_mimes {@link http://codex.wordpress.org/Plugin_API/Filter_Reference filter}
  656.      * called by WordPress.
  657.      *
  658.      * @since 1.3
  659.      */
  660.     public function upload_mimes( $mimes ) {
  661.         $mimes['kml'] = 'application/vnd.google-earth.kml+xml';
  662.         $mimes['kmz'] = 'application/vnd.google-earth.kmz';
  663.         $mimes['gpx'] = 'application/octet-stream';
  664.         return $mimes;
  665.     }
  666.  
  667.     /**
  668.      * If an upload is KML, put the URL in an option to be loaded in the response
  669.      * 
  670.      * wp_handle_upload {@link http://codex.wordpress.org/Plugin_API/Filter_Reference filter}
  671.      * called by WordPress.
  672.      *
  673.      * @since 1.3
  674.      */
  675.     public function wp_handle_upload( $args ) {
  676.         // TODO: use transient API instead of option
  677.         delete_transient( 'gm_uploaded_kml_url' );
  678.         if ( is_array( $args ) && isset( $args['file'] ) ) {
  679.             if ( stripos( $args['file'], '.km' ) == strlen( $args['file'] ) - 4 ) {
  680.                 set_transient( 'gm_uploaded_kml_url', $args['url'] );
  681.             }
  682.         }
  683.         return $args;
  684.     }
  685. }
  686.  
  687. // Instantiate
  688.  
  689. /**
  690.  * A manager for comment location user interfaces.
  691.  *
  692.  * Singleton instantiated immediately.
  693.  *
  694.  * @package GeoMashup
  695.  * @since 1.3
  696.  * @access public
  697.  */
  698.     /**
  699.      * Whether to put the comment form script in the footer.
  700.      *
  701.      * @since 1.4
  702.      */
  703.     private $add_form_script = false;
  704.  
  705.     /**
  706.      * Get the single instance of this class.
  707.      * 
  708.      * @since 1.3
  709.      *
  710.      * @return GeoMashupPostUIManager The instance.
  711.      */
  712.     public static function get_instance() {
  713.         static $instance = null;
  714.         if ( is_null( $instance ) ) {
  715.             $instance = new GeoMashupCommentUIManager();
  716.         }
  717.         return $instance;
  718.     }
  719.  
  720.     /**
  721.      * PHP5 Constructor
  722.      *
  723.      * @since 1.3
  724.      */
  725.     public function __construct() {
  726.         // Global $geo_mashup_options is available, but a better pattern might
  727.         // be to wait until init to be sure
  728.         add_action( 'init', array( &$this, 'init' ) );
  729.     }
  730.  
  731.     /**
  732.      * Initialize for use in relevant requests.
  733.      *
  734.      * init {@link http://codex.wordpress.org/Plugin_API/Action_Reference action}
  735.      * called by WordPress.
  736.      * 
  737.      * @since 1.3
  738.      * @global array $geo_mashup_options 
  739.      * @uses apply_filters geo_mashup_load_comment_editor Returns a boolean that loads the editor when true.
  740.      */
  741.     public function init() {
  742.         global $geo_mashup_options;
  743.  
  744.         $load_comment_editor = ( !is_admin() && $geo_mashup_options->get( 'overall', 'located_object_name', 'comment' ) == 'true' ); 
  745.         $load_comment_editor = apply_filters( 'geo_mashup_load_comment_editor', $load_comment_editor );
  746.  
  747.         // If enabled, register all the interface elements
  748.         if ( $load_comment_editor ) {
  749.  
  750.             // Form generation
  751.             add_action( 'comment_form', array( &$this, 'print_form' ) );
  752.  
  753.             // Form script
  754.             add_action( 'wp_footer', array( &$this, 'wp_footer' ) );
  755.  
  756.             // Form processing
  757.             add_action( 'comment_post', array( &$this, 'save_comment'), 10, 2 );
  758.  
  759.             wp_enqueue_script( 'geo-mashup-loader' );
  760.         }
  761.     }
  762.  
  763.     /**
  764.      * Print the comment location editor form.
  765.      *
  766.      * @since 1.3
  767.      * @access public
  768.      */
  769.     public function print_form() {
  770.         $this->add_form_script = true;
  771.  
  772.         // If there's a logged in user with a location, use that as a default.
  773.         // The client-side location will override it if available
  774.         $user = wp_get_current_user();
  775.         if ( $user ) 
  776.             $default_location = GeoMashupDB::get_object_location( 'user', $user->ID );
  777.         if ( !$default_location )
  778.             $default_location = GeoMashupDB::blank_object_location();
  779.         $default_summary = ( empty( $default_location->locality_name ) ? '' : $default_location->locality_name . ', ' ) .
  780.                 ( empty( $default_location->admin_code ) ? '' : $default_location->admin_code );
  781.  
  782.         // Print the form
  783.         printf( '<label id="geo-mashup-summary-label" for="geo-mashup-summary-input" style="display:none;">%s</label>', __( 'Written from (location)', 'GeoMashup' ) );
  784.         printf( '<input id="geo-mashup-summary-input" style="display:none;" type="text" size="25" value="%s" />', $default_summary );
  785.         printf( '<img id="geo-mashup-busy-icon" style="display:none;" src="%s" alt="%s" />', path_join( GEO_MASHUP_URL_PATH, 'images/busy_icon.gif' ), __( 'Loading...', 'GeoMashup' ) );
  786.         $input_format = '<input id="geo-mashup-%s-input" name="comment_location[%s]" type="hidden" value="%s" />';
  787.         printf( $input_format, 'lat', 'lat', $default_location->lat );
  788.         printf( $input_format, 'lng', 'lng', $default_location->lng );
  789.     }
  790.  
  791.     /**
  792.      * Print the form script in the footer if it's needed.
  793.      *
  794.      * @since 1.4
  795.      */
  796.     public function wp_footer() {
  797.         global $geo_mashup_options;
  798.         if ( $this->add_form_script ) {
  799.             GeoMashup::register_script( 'geo-mashup-comment-form', 'js/comment-form.js', array( 'jquery' ), GEO_MASHUP_VERSION, true );
  800.             wp_localize_script( 'geo-mashup-comment-form', 'geo_mashup_comment_form_settings', array( 'geonames_username' => $geo_mashup_options->get( 'overall', 'geonames_username' ) ) );
  801.             wp_print_scripts( 'geo-mashup-comment-form' );
  802.         }
  803.     }
  804.  
  805.     /**
  806.      * When a comment is saved, save any posted location with it.
  807.      *
  808.      * save_comment {@link http://codex.wordpress.org/Plugin_API/Filter_Reference filter}
  809.      * called by WordPress.
  810.      *
  811.      * @since 1.3
  812.      * @uses GeoMashupDB::set_object_location()
  813.      */
  814.     public function save_comment( $comment_id = 0, $approval = '' ) {
  815.         if ( !$comment_id || 'spam' === $approval || empty( $_POST['comment_location'] ) || !is_array( $_POST['comment_location'] ) ) {
  816.             return false;
  817.         }
  818.  
  819.         GeoMashupDB::set_object_location( 'comment', $comment_id, $_POST['comment_location'] );
  820.     }
  821. }
  822.  
  823. // Instantiate

Documentation generated on Sat, 09 Jul 2011 21:54:47 -0700 by phpDocumentor 1.4.3