Source for file geo-mashup-ui-managers.php
Documentation is available at geo-mashup-ui-managers.php 
 * Geo Mashup "core" implementation of location management user interfaces.  
 * Theoretically, everything done here could be done in a separate plugin.  
 * A base class for managing user interfaces for collecting and storing location.  
 * This could be extended to make the existing editor work for new objects in a separate plugin.  
     * Retrieve a single instaniated subclass by name.  
     * @param string $name The class name of the manager.  
     * @return GeoMashupUIManager The singleton object.  
        static $instances =  array();  
        if ( ! isset ( $instances[$name] ) ) {  
            $instances[$name] =  new $name();  
        return $instances[$name];  
     * Queue UI styles to match the jQuery version.  
        GeoMashup::register_style( 'jquery-smoothness', 'css/jquery-ui.1.7.smoothness.css', false, GEO_MASHUP_VERSION, 'screen' );  
        wp_enqueue_style( 'jquery-smoothness' );  
     * Queue styles and scripts for the location editor form.  
        GeoMashup::register_style( 'geo-mashup-edit-form', 'css/location-editor.css', false, GEO_MASHUP_VERSION, 'screen' );  
        wp_enqueue_style( 'geo-mashup-edit-form' );  
        $map_api =  $geo_mashup_options->get( 'overall', 'map_api' );  
        $geonames_username =  $geo_mashup_options->get( 'overall', 'geonames_username' );  
        $ajax_nonce =  wp_create_nonce('geo-mashup-ajax-edit');  
        $ajax_url =  admin_url( 'admin-ajax.php' );  
        $geo_mashup_url_path =  GEO_MASHUP_URL_PATH;  
        wp_localize_script( 'mxn-core', 'geo_mashup_location_editor_settings', compact( 'map_api', 'ajax_url', 'geo_mashup_url_path', 'geonames_username' ) );  
        $required_scripts =  array( 'jquery');  
        if ( 'google' ==  $map_api ) {  
            wp_register_script( 'google-maps-2', 'http://maps.google.com/maps?file=api&v=2&sensor=false&key=' .    
            GeoMashup::register_script( 'mxn-google-2', 'js/mxn/mxn.google.core.js', array( 'mxn-core', 'google-maps-2' ), GEO_MASHUP_VERSION );  
            GeoMashup::register_script( 'mxn-google-2-gm', 'js/mxn/mxn.google.geo-mashup.js', array( 'mxn-google-2' ), GEO_MASHUP_VERSION );  
            $required_scripts[] =  'mxn-google-2-gm';  
        } else if ( 'googlev3' ==  $map_api ) {  
            wp_register_script( 'google-maps-3', 'http://maps.google.com/maps/api/js?sensor=false&language=' .  GeoMashup::get_language_code() );  
            GeoMashup::register_script( 'mxn-google-3', 'js/mxn/mxn.googlev3.core.js', array( 'mxn-core', 'google-maps-3' ), GEO_MASHUP_VERSION );  
            GeoMashup::register_script( 'mxn-google-3-gm', 'js/mxn/mxn.googlev3.geo-mashup.js', array( 'mxn-google-3' ), GEO_MASHUP_VERSION );  
            $required_scripts[] =  'mxn-google-3-gm';  
        } else if ( 'openlayers' ==  $map_api ) {  
            wp_register_script( 'openlayers', 'http://openlayers.org/api/OpenLayers.js', null, 'latest' );  
            wp_register_script( 'openstreetmap', 'http://www.openstreetmap.org/openlayers/OpenStreetMap.js', array( 'openlayers' ), 'latest' );  
            GeoMashup::register_script( 'mxn-openlayers', 'js/mxn/mxn.openlayers.core.js', array( 'mxn-core', 'openstreetmap' ), GEO_MASHUP_VERSION );  
            GeoMashup::register_script( 'mxn-openlayers-gm', 'js/mxn/mxn.openlayers.geo-mashup.js', array( 'mxn-openlayers' ), GEO_MASHUP_VERSION );  
            $required_scripts[] =  'mxn-openlayers-gm';  
        GeoMashup::register_script( 'geo-mashup-location-editor', 'js/location-editor.js', $required_scripts, GEO_MASHUP_VERSION );  
        wp_enqueue_script( 'geo-mashup-location-editor' );  
        GeoMashup::register_script( 'jquery-ui-datepicker', 'js/jquery-ui.1.7.3.datepicker.js', array( 'jquery', 'jquery-ui-core'), '1.7.3' );  
        wp_enqueue_script( 'jquery-ui-datepicker' );  
        if ( isset ( $geo_mashup_custom ) ) {  
            $custom_url =  $geo_mashup_custom->file_url( 'location-editor.js' );  
            if ( ! empty( $custom_url ) ) {  
                wp_enqueue_script( 'geo-mashup-location-editor-custom', $custom_url, array( 'geo-mashup-location-editor' ) );  
     * Determine the appropriate action from posted data.  
    private function get_submit_action() {  
        if ( isset ( $_POST['geo_mashup_add_location'] ) or isset ( $_POST['geo_mashup_update_location'] ) ) {  
            // Clients without javascript may need server side geocoding  
            if ( ! empty( $_POST['geo_mashup_search'] ) and isset ( $_POST['geo_mashup_no_js'] ) and 'true' ==  $_POST['geo_mashup_no_js'] ) {  
        } else if ( isset ( $_POST['geo_mashup_changed'] ) and 'true' ==  $_POST['geo_mashup_changed'] and ! empty( $_POST['geo_mashup_location'] ) ) {  
            // The geo mashup submit button wasn't used, but a change was made and the post saved  
        } else if ( isset ( $_POST['geo_mashup_delete_location'] ) ) {  
        } else if ( ! empty( $_POST['geo_mashup_location_id'] ) and empty( $_POST['geo_mashup_location'] ) ) {  
            // There was a location, but it was cleared before this save  
     * Save an object location from data posted by the location editor.  
     * @uses GeoMashupDB::set_object_location()  
     * @uses GeoMashupDB::delete_location()  
     * @param string $object_name The name of the object being edited.  
     * @param string $object_id The ID of the object being edited.  
     * @return bool|WP_ErrorTrue or a WordPress error.  
        if ( empty( $_POST['geo_mashup_nonce'] ) ||  !wp_verify_nonce( $_POST['geo_mashup_nonce'], 'geo-mashup-edit' ) ) {  
            return new WP_Error( 'invalid_request', __( 'Object location not saved - invalid request.', 'GeoMashup' ) );  
        $action =  $this->get_submit_action();  
        if ( 'save' ==  $action or 'geocode' ==  $action ) {  
            $date_string =  $_POST['geo_mashup_date'] .  ' ' .  $_POST['geo_mashup_hour'] .  ':' .    
                $_POST['geo_mashup_minute'] .  ':00';  
            $post_location =  array();  
            // If PHP has added slashes, WP will do it again before saving  
            $post_location['saved_name'] =  stripslashes( $_POST['geo_mashup_location_name'] );  
            if ( 'geocode' ==  $action ) {  
                    $post_location =  array();  
                if ( ! empty( $_POST['geo_mashup_select'] ) ) {  
                    $selected_items =  explode( '|', $_POST['geo_mashup_select'] );  
                    $post_location =  intval( $selected_items[0] );  
                    $post_location['id'] =  $_POST['geo_mashup_location_id'];  
                    list ( $lat, $lng ) =  split( ',', $_POST['geo_mashup_location'] ); 
                    $post_location['lat'] =  trim( $lat );  
                    $post_location['lng'] =  trim( $lng );  
                    $post_location['geoname'] =  $_POST['geo_mashup_geoname'];  
                    $post_location['address'] =  stripslashes( $_POST['geo_mashup_address'] );  
                    $post_location['postal_code'] =  $_POST['geo_mashup_postal_code'];  
                    $post_location['country_code'] =  $_POST['geo_mashup_country_code'];  
                    $post_location['admin_code'] =  $_POST['geo_mashup_admin_code'];  
                    $post_location['sub_admin_code'] =  $_POST['geo_mashup_sub_admin_code'];  
                    $post_location['locality_name'] =  $_POST['geo_mashup_locality_name'];  
            if ( ! empty( $post_location ) ) {  
                if ( is_wp_error( $error ) )   
        } else if ( 'delete' ==  $action ) {  
            if ( is_wp_error( $error ) )   
        // If geodata was manually updated but Geo Mashup location was not,  
        // they may be out of sync now. Allowing that for now.  
 * A manager for user location user interfaces.  
 * Singleton instantiated immediately.  
     * Get the single instance of this class.  
     * @uses parent::get_instance()  
     * @return GeoMashupPostUIManager The instance.  
        // Global $geo_mashup_options is available, but a better pattern might  
        // be to wait until init to be sure  
        add_action( 'init', array( &$this, 'init' ) );  
     * Initialize for use in relevant requests.  
     * init {@link http://codex.wordpress.org/Plugin_API/Action_Reference action}  
     * @global array $geo_mashup_options   
     * @global string $pagenow The WordPress-supplied requested filename.  
     * @uses apply_filters geo_mashup_load_user_editor Returns a boolean that loads the editor when true.  
        // Enable this interface when the option is set and we're on a destination page  
            $geo_mashup_options->get( 'overall', 'located_object_name', 'user' ) ==  'true' &&   
            preg_match( '/(user-edit|user-new|profile).php/', $pagenow );  
        $enabled =  apply_filters( 'geo_mashup_load_user_editor', $enabled );  
        // If enabled, register all the interface elements  
            add_action( 'show_user_profile', array( &$this, 'print_form' ) );  
            add_action( 'edit_user_profile', array( &$this, 'print_form' ) );  
            // MAYBEDO: add location to registration page?  
            add_action( 'personal_options_update', array( &$this, 'save_user'));  
            add_action( 'edit_user_profile_update', array( &$this, 'save_user'));  
     * Print the user location editor form.  
        include_once( GEO_MASHUP_DIR_PATH .  '/edit-form.php');  
        if ( isset ( $_GET['user_id'] ) ) {  
            $object_id =  $_GET['user_id'];  
        echo  '<h3>' .  __( 'Location', 'GeoMashup' ) .  '</h3>'; 
     * Save a posted user location.  
     * @uses parent::save_posted_object_location()  
     * When a user is saved, also save any posted location.  
     * save_user {@link http://codex.wordpress.org/Plugin_API/Action_Reference action}  
        if ( empty( $_POST['user_id'] ) ) {  
        $user_id =  $_POST['user_id'];  
        if ( !current_user_can( 'edit_user', $user_id ) ) {  
 * A manager for post/page location user interfaces.  
 * Singleton instantiated immediately.  
     * Location found in geo_mashup_save_location shortcode.  
    private $inline_location;  
     * Get the single instance of this class.  
     * @uses parent::get_instance()  
     * @return GeoMashupPostUIManager The instance.  
        // Global $geo_mashup_options is available, but a better pattern might  
        // be to wait until init to be sure  
        add_action( 'init', array( &$this, 'init' ) );  
     * Initialize for use in relevant post editing requests.  
     * init {@link http://codex.wordpress.org/Plugin_API/Action_Reference action}  
     * @global array $geo_mashup_options   
     * @global string $pagenow The WordPress-supplied requested filename.  
     * @uses apply_filters geo_mashup_load_location_editor Returns a boolean that loads the editor when true.  
        // Uploadable geo content type expansion always enabled  
        add_filter( 'upload_mimes', array( &$this, 'upload_mimes' ) );  
        // Queue inline location handlers - these could be used in nearly any request  
        // Pre-save filter checks saved content for inline location tags  
        add_filter( 'content_save_pre', array( &$this, 'content_save_pre') );  
        // Save post handles both inline and form processing  
        add_action( 'save_post', array( &$this, 'save_post'), 10, 2 );  
        // Browser upload processing  
        add_filter( 'wp_handle_upload', array( &$this, 'wp_handle_upload' ) );  
        // Enable front or back end ajax edits  
        add_action( 'wp_ajax_nopriv_geo_mashup_edit', array( 'GeoMashup', 'ajax_edit' ) );  
        add_action( 'wp_ajax_geo_mashup_edit', array( 'GeoMashup', 'ajax_edit' ) );  
        add_action( 'admin_menu', array( &$this, 'admin_menu' ) );  
        // Queue scripts later, when we can determine post type, front or back end  
        add_action( 'admin_enqueue_scripts', array( &$this, 'enqueue_scripts' ) );  
        add_action( 'wp_enqueue_scripts', array( &$this, 'enqueue_scripts' ) );  
        if ( 'async-upload.php' ===  $pagenow ) {  
            add_filter( 'media_meta', array( &$this, 'media_meta' ), 10, 2 );  
        } else if ( 'upload.php' ===  $pagenow or 'media-upload.php' ===  $pagenow ) {  
            // Browser upload display  
            add_action( 'admin_print_scripts', array( &$this, 'admin_print_scripts' ) );  
     * Queue scripts if the post type is enabled.  
     * Monitor for checking post type: http://core.trac.wordpress.org/ticket/14886  
     * @uses apply_filters geo_mashup_load_location_editor intended for enabling a front end interface  
     * @global array $geo_mashup_options   
     * @global string $pagenow   
        // The location editor works only on posts  
        $load_location_editor =  (  
                preg_match( '/(post|page)(-new|).php/', $pagenow ) and  
                in_array( $post->post_type, $geo_mashup_options->get( 'overall', 'located_post_types' ) )  
        $load_location_editor =  apply_filters( 'geo_mashup_load_location_editor', $load_location_editor );  
        // If we're on a post editing page, queue up the form interface elements  
        if ( $load_location_editor ) {  
     * Add a location meta box to the post editors.  
     * admin_menu {@link http://codex.wordpress.org/Plugin_API/Action_Reference action}  
        // Not adding a menu, but at this stage add_meta_box is defined, so we can add the location form  
        foreach ( $geo_mashup_options->get( 'overall', 'located_post_types' ) as $post_type ) {  
            add_meta_box( 'geo_mashup_post_edit', __( 'Location', 'GeoMashup' ), array( &$this, 'print_form' ), $post_type, 'advanced' );  
     * Print the post editor form.  
        include_once( GEO_MASHUP_DIR_PATH .  '/edit-form.php');  
     * Save a posted post or page location.  
     * @uses parent::save_posted_object_location()  
     * When a post is saved, save any posted location for it.  
     * save_post {@link http://codex.wordpress.org/Plugin_API/Action_Reference action}  
     * @uses GeoMashupDB::set_object_location()  
        if ( 'revision' ==  $post->post_type ) {  
        // WP has already saved the post - allow location saving without added capability checks  
        if ( !empty( $this->inline_location ) ) {  
            if ( isset ( $this->inline_location['geo_date'] ) ) {  
                $geo_date =  $this->inline_location['geo_date'];  
                unset ( $this->inline_location['geo_date'] ); 
            if ( is_wp_error( $location_id ) ) {  
                update_post_meta( $post_id, 'geo_mashup_save_location_error', $location_id->get_error_message() );  
            $this->inline_location =  null;  
        delete_transient( 'gm_uploaded_kml_url' );  
     * Extract inline save location shortcodes from post content before it is saved.  
     * content_save_pre {@link http://codex.wordpress.org/Plugin_API/Filter_Reference filter}  
        // Piggyback on the shortcode interface to find inline tags [geo_mashup_save_location ...]   
        add_shortcode( 'geo_mashup_save_location', 'is_null' );  
        $pattern =  get_shortcode_regex( );  
        return preg_replace_callback('/'. $pattern. '/s', array( &$this, 'replace_save_pre_shortcode' ), $content);  
     * Store the inline location from a save location shortcode before it is removed.  
     * @param array $shortcode_match   
     * @return The matched content, or an empty string if it was a save location shortcode.  
        $content =  $shortcode_match[0];  
        $tag_index =  array_search( 'geo_mashup_save_location',  $shortcode_match );   
        if ( $tag_index !==  false ) {  
            // There is an inline location - save the attributes  
            $this->inline_location =  shortcode_parse_atts( stripslashes( $shortcode_match[$tag_index+ 1] ) );  
            // If lat and lng are missing, try to geocode based on address  
            if ( ( empty( $this->inline_location['lat'] ) or empty( $this->inline_location['lng'] ) ) and !empty( $this->inline_location['address'] ) ) {  
                $query =  $this->inline_location['address'];  
                $message =  ( is_wp_error( GeoMashupDB::$geocode_error ) ?  GeoMashupDB::$geocode_error->get_error_message() :  __( 'Address not found - try making it less detailed', 'GeoMashup' ) );  
                $content =  str_replace( ']', ' geocoding_error="' .  $message .  '"]', $content );  
                $this->inline_location =  null;  
     * Add Flash-uploaded KML to the location editor map.  
     * media_meta {@link http://codex.wordpress.org/Plugin_API/Filter_Reference filter}  
        // Only chance to run some javascript after a flash upload?  
        if (strlen($post->guid) >  0) {  
            $content .=  '<script type="text/javascript"> ' .   
                'if (\'GeoMashupLocationEditor\' in parent) parent.GeoMashupLocationEditor.loadKml(\''. $post->guid. '\');' .   
     * Add Browser-uploaded KML to the location editor map.  
     * admin_print_scripts {@link http://codex.wordpress.org/Plugin_API/Action_Reference action}  
        // Load any uploaded KML into the search map - only works with browser uploader  
        // See if wp_upload_handler found uploaded KML  
        $kml_url =  get_transient( 'gm_uploaded_kml_url' );  
            // Load the KML in the location editor  
                <script type="text/javascript">   
                    if (\'GeoMashupLocationEditor\' in parent) parent.GeoMashupLocationEditor.loadKml(\'' .  $kml_url .  '\');  
            delete_transient( 'gm_uploaded_kml_url' );  
     * Add geo mime types to allowable uploads.  
     * upload_mimes {@link http://codex.wordpress.org/Plugin_API/Filter_Reference filter}  
        $mimes['kml'] =  'application/vnd.google-earth.kml+xml';  
        $mimes['kmz'] =  'application/vnd.google-earth.kmz';  
        $mimes['gpx'] =  'application/octet-stream';  
     * If an upload is KML, put the URL in an option to be loaded in the response  
     * wp_handle_upload {@link http://codex.wordpress.org/Plugin_API/Filter_Reference filter}  
        // TODO: use transient API instead of option  
        delete_transient( 'gm_uploaded_kml_url' );  
        if ( is_array( $args ) && isset ( $args['file'] ) ) {  
            if ( stripos( $args['file'], '.km' ) ==  strlen( $args['file'] ) -  4 ) {  
                set_transient( 'gm_uploaded_kml_url', $args['url'] );  
 * A manager for comment location user interfaces.  
 * Singleton instantiated immediately.  
     * Whether to put the comment form script in the footer.  
    private $add_form_script =  false;  
     * Get the single instance of this class.  
     * @return GeoMashupPostUIManager The instance.  
        if ( is_null( $instance ) ) {  
            $instance =  new GeoMashupCommentUIManager();  
        // Global $geo_mashup_options is available, but a better pattern might  
        // be to wait until init to be sure  
        add_action( 'init', array( &$this, 'init' ) );  
     * Initialize for use in relevant requests.  
     * init {@link http://codex.wordpress.org/Plugin_API/Action_Reference action}  
     * @global array $geo_mashup_options   
     * @uses apply_filters geo_mashup_load_comment_editor Returns a boolean that loads the editor when true.  
        $load_comment_editor =  ( !is_admin() &&  $geo_mashup_options->get( 'overall', 'located_object_name', 'comment' ) ==  'true' );   
        $load_comment_editor =  apply_filters( 'geo_mashup_load_comment_editor', $load_comment_editor );  
        // If enabled, register all the interface elements  
        if ( $load_comment_editor ) {  
            add_action( 'comment_form', array( &$this, 'print_form' ) );  
            add_action( 'wp_footer', array( &$this, 'wp_footer' ) );  
            add_action( 'comment_post', array( &$this, 'save_comment'), 10, 2 );  
            wp_enqueue_script( 'geo-mashup-loader' );  
     * Print the comment location editor form.  
        $this->add_form_script =  true;  
        // If there's a logged in user with a location, use that as a default.  
        // The client-side location will override it if available  
        $user =  wp_get_current_user();  
        if ( !$default_location )  
        $default_summary =  ( empty( $default_location->locality_name ) ?  '' :  $default_location->locality_name .  ', ' ) .   
                ( empty( $default_location->admin_code ) ?  '' :  $default_location->admin_code );  
        printf( '<label id="geo-mashup-summary-label" for="geo-mashup-summary-input" style="display:none;">%s</label>', __( 'Written from (location)', 'GeoMashup' ) );  
        printf( '<input id="geo-mashup-summary-input" style="display:none;" type="text" size="25" value="%s" />', $default_summary );  
        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' ) );  
        $input_format =  '<input id="geo-mashup-%s-input" name="comment_location[%s]" type="hidden" value="%s" />';  
        printf( $input_format, 'lat', 'lat', $default_location->lat );  
        printf( $input_format, 'lng', 'lng', $default_location->lng );  
     * Print the form script in the footer if it's needed.  
        if ( $this->add_form_script ) {  
            GeoMashup::register_script( 'geo-mashup-comment-form', 'js/comment-form.js', array( 'jquery' ), GEO_MASHUP_VERSION, true );  
            wp_localize_script( 'geo-mashup-comment-form', 'geo_mashup_comment_form_settings', array( 'geonames_username' =>  $geo_mashup_options->get( 'overall', 'geonames_username' ) ) );  
            wp_print_scripts( 'geo-mashup-comment-form' );  
     * When a comment is saved, save any posted location with it.  
     * save_comment {@link http://codex.wordpress.org/Plugin_API/Filter_Reference filter}  
     * @uses GeoMashupDB::set_object_location()  
    public function save_comment( $comment_id =  0, $approval =  '' ) {  
        if ( !$comment_id ||  'spam' ===  $approval ||  empty( $_POST['comment_location'] ) ||  !is_array( $_POST['comment_location'] ) ) {  
 
 
        
       |