Kind of a front controller.
Author: Inpsyde GmbH, toscho
/**
 * Initialize the plugin.
 *
 * @wp-hook plugins_loaded
 *
 * @return void
 */
function mlp_init()
{
    global $pagenow, $wp_version, $wpdb;
    $plugin_path = plugin_dir_path(__FILE__);
    $plugin_url = plugins_url('/', __FILE__);
    $assets_base = 'assets';
    if (!class_exists('Mlp_Load_Controller')) {
        require $plugin_path . 'inc/autoload/Mlp_Load_Controller.php';
    }
    $loader = new Mlp_Load_Controller($plugin_path . 'inc');
    $data = new Mlp_Plugin_Properties();
    $data->set('loader', $loader->get_loader());
    $locations = new Mlp_Internal_Locations();
    $locations->add_dir($plugin_path, $plugin_url, 'plugin');
    $assets_locations = array('css' => 'css', 'js' => 'js', 'images' => 'images', 'flags' => 'images/flags');
    foreach ($assets_locations as $type => $dir) {
        $locations->add_dir($plugin_path . $assets_base . '/' . $dir, $plugin_url . $assets_base . '/' . $dir, $type);
    }
    $data->set('locations', $locations);
    $data->set('plugin_file_path', __FILE__);
    $data->set('plugin_base_name', plugin_basename(__FILE__));
    $headers = get_file_data(__FILE__, array('text_domain_path' => 'Domain Path', 'plugin_uri' => 'Plugin URI', 'plugin_name' => 'Plugin Name', 'version' => 'Version'));
    foreach ($headers as $name => $value) {
        $data->set($name, $value);
    }
    if (!mlp_pre_run_test($pagenow, $data, $wp_version, $wpdb)) {
        return;
    }
    $mlp = new Multilingual_Press($data, $wpdb);
    $mlp->setup();
}
 /**
  * Determine the current module state (on/off).
  * NOTE: the module file must correspond
  * with the 'slug' provided, i.e. cpt-module.php
  * must have 'cpt-module' as a slug parameter.
  *
  * @access	private
  * @since	0.1
  * @return	FALSE | if turned off
  */
 private function module_init()
 {
     // Check module state
     $module_init = array('display_name' => 'User Backend Language', 'slug' => 'class-' . __CLASS__);
     if ('off' === parent::get_module_state($module_init)) {
         return FALSE;
     }
 }
 /**
  * Determine the current module state (on/off).
  *
  * @since 0.1
  * @return FALSE  | if turned off
  */
 private function module_init()
 {
     // Check module state
     $module_init = array('display_name' => __('Default Actions', 'multilingualpress'), 'slug' => 'class-' . __CLASS__);
     if ('off' === parent::get_module_state($module_init)) {
         return FALSE;
     }
 }
 /**
  * Determine the current module state (on/off).
  * NOTE: the module file must correspond
  * with the 'slug' provided, i.e. cpt-module.php
  * must have 'cpt-module' as a slug parameter.
  *
  * @access	private
  * @since	0.1
  * @return	FALSE | if turned off
  */
 private function module_init()
 {
     // Check module state
     $module_init = array('display_name' => 'Custom Post Types', 'slug' => 'class-' . __CLASS__);
     if ('off' === parent::get_module_state($module_init)) {
         return FALSE;
     }
 }
 /**
  * Initial setup handler.
  *
  * @global	$wpdb wpdb WordPress Database Wrapper
  * @global	$pagenow string Current Page Wrapper
  * @return void
  */
 public function setup()
 {
     global $pagenow;
     $this->link_table = $this->wpdb->base_prefix . 'multilingual_linked';
     $this->plugin_dir_path = $this->plugin_data->plugin_dir_path;
     $this->plugin_file_path = $this->plugin_data->plugin_file_path;
     $this->plugin_data->module_manager = new Mlp_Module_Manager('state_modules');
     $this->plugin_data->site_manager = new Mlp_Module_Manager('inpsyde_multilingual');
     $this->plugin_data->link_table = $this->link_table;
     $this->plugin_data->content_relations = new Mlp_Content_Relations($this->wpdb, $this->plugin_data->site_relations, $this->link_table);
     $this->plugin_data->language_api = new Mlp_Language_Api($this->plugin_data, 'mlp_languages', $this->plugin_data->site_relations, $this->plugin_data->content_relations, $this->wpdb);
     $this->plugin_data->assets = new Mlp_Assets($this->plugin_data->locations);
     $this->load_assets();
     Mlp_Helpers::$link_table = $this->link_table;
     Mlp_Helpers::insert_dependency('site_relations', $this->plugin_data->site_relations);
     Mlp_Helpers::insert_dependency('language_api', $this->plugin_data->language_api);
     Mlp_Helpers::insert_dependency('plugin_data', $this->plugin_data);
     $this->plugin_data->freeze();
     // no changes allowed anymore
     require 'functions.php';
     // This check prevents the use of this plugin in a not-setted blog
     if ('admin-post.php' != $pagenow && 'admin-ajax.php' != $pagenow && !is_network_admin() && !array_key_exists(get_current_blog_id(), get_site_option('inpsyde_multilingual', array()))) {
         return;
     }
     // The Plugins Basename
     // used by features/class-Multilingual_Press_Auto_Update.php only
     self::$plugin_base_name = $this->plugin_data->plugin_base_name;
     // The Plugins URL
     self::$plugin_url = $this->plugin_data->plugin_uri;
     // The Plugins Name
     self::$plugin_name = $this->plugin_data->plugin_name;
     // Textdomain Path
     self::$textdomainpath = $this->plugin_data->text_domain_path;
     // Hooks and filters
     add_action('inpsyde_mlp_loaded', array($this, 'load_plugin_textdomain'), 1);
     // Load modules
     $this->load_features();
     /**
      * Kick-Off Init
      * @return  Void
      */
     do_action('inpsyde_mlp_init', $this->plugin_data);
     // Enqueue scripts
     add_action('admin_enqueue_scripts', array($this, 'admin_scripts'));
     // Cleanup upon blog delete
     add_filter('delete_blog', array($this, 'delete_blog'), 10, 2);
     // Checkup blog cleanup
     add_filter('admin_head', array($this, 'checkup_blog_message'));
     add_filter('wp_ajax_checkup_blogs', array($this, 'checkup_blog'));
     // Check for errors
     add_filter('all_admin_notices', array($this, 'check_for_user_errors_admin_notice'));
     add_action('wp_loaded', array($this, 'late_load'), 0);
     /**
      * Everything loaded
      * @param   Inpsyde_Property_List_Interface
      */
     do_action('inpsyde_mlp_loaded', $this->plugin_data);
     if (is_admin()) {
         if ($this->plugin_data->module_manager->has_modules()) {
             $this->load_module_settings_page();
         }
         if ($this->plugin_data->site_manager->has_modules()) {
             $this->load_site_settings_page();
         }
         new Mlp_Network_Site_Settings_Controller($this->plugin_data);
         new Mlp_Network_New_Site_Controller($this->plugin_data->language_api, $this->plugin_data->site_relations);
     } else {
         // frontend-hooks
         $hreflang = new Mlp_Hreflang_Header_Output($this->plugin_data->language_api);
         add_action('template_redirect', array($hreflang, 'http_header'));
         add_action('wp_head', array($hreflang, 'wp_head'));
     }
 }
 /**
  * Bootstraps MultilingualPress.
  *
  * @since 3.0.0
  *
  * @return bool Whether or not MultilingualPress was bootstrapped successfully.
  *
  * @throws BadMethodCallException if called on a MultilingualPress instance that has already been bootstrapped.
  */
 public function bootstrap()
 {
     if ($this->is_bootstrapped) {
         throw new BadMethodCallException('Cannot bootstrap a MultilingualPress instance that has already been bootstrapped.');
     }
     /**
      * Fires right before MultilingualPress gets bootstrapped.
      *
      * Hook here to register custom service providers.
      *
      * @since 3.0.0
      *
      * @param static $multilingualpress MultilingualPress instance.
      */
     do_action('multilingualpress.bootstrap', $this);
     static::$container->lock();
     // TODO: Eventually remove the following block.
     class_exists('Mlp_Load_Controller') or (require __DIR__ . '/inc/autoload/Mlp_Load_Controller.php');
     new \Mlp_Load_Controller(static::$container['multilingualpress.properties']->plugin_dir_path() . '/src/inc');
     if (!$this->check_installation()) {
         return false;
     }
     $this->bootstrap_service_providers();
     $needs_modules = $this->needs_modules();
     if ($needs_modules) {
         /**
          * Fires right before MultilingualPress registers any modules.
          *
          * @since 3.0.0
          */
         do_action('multilingualpress.register_modules');
         $this->register_modules();
     }
     unset($this->modules);
     static::$container->bootstrap();
     $this->is_bootstrapped = true;
     // TODO: Remove as soon as the old front controller has been replaced completely.
     class_exists('Multilingual_Press') or (require __DIR__ . '/inc/Multilingual_Press.php');
     // TODO: Refactor according to new architecure.
     $old_controller = new \Multilingual_Press(static::$container);
     $old_controller->prepare_plugin_data();
     if (!$needs_modules) {
         return true;
     }
     load_plugin_textdomain('multilingual-press');
     if (is_admin()) {
         $this->bootstrap_admin();
     } else {
         $this->bootstrap_front_end();
     }
     // TODO: Refactor according to new architecure.
     $old_controller->setup();
     return true;
 }
 /**
  * Registers the widget and set up the description
  *
  * @since	0.1
  * @access	public
  * @uses	Multilingual_Press, __
  * @return	void
  */
 public function mlp_widget()
 {
     $mlp = Multilingual_Press::get_object();
     $widget_ops = array('classname' => 'Mlp_Widget', 'description' => __('Multilingual Press Widget', 'multilingualpress'));
     $this->WP_Widget('Mlp_Widget', __('Multilingual Press Widget', 'multilingualpress'), $widget_ops);
 }
 /**
  * Determine the current module state (on/off).
  * NOTE: the module file must correspond
  * with the 'slug' provided, i.e. cpt-module.php
  * must have 'cpt-module' as a slug parameter.
  *
  * @since	0.1
  * @access	private
  * @return	FALSE | if turned off
  */
 private function module_init()
 {
     // Check module state
     $module_init = array('display_name' => 'Quicklink', 'slug' => 'class-' . __CLASS__, 'deactivation' => array('Multilingual_Press_Quicklink', 'deactivate_module'));
     if ('off' === parent::get_module_state($module_init)) {
         return FALSE;
     }
 }
 /**
  * create the element on other blogs and link them
  *
  * @access  public
  * @since   0.1
  * @uses	get_post_status, get_post, get_post_thumbnail_id, wp_upload_dir, get_post_meta,
  *			pathinfo, get_blog_list, get_current_blog_id, switch_to_blog, wp_insert_post,
  *			wp_unique_filename, wp_check_filetype, is_wp_error, wp_update_attachment_metadata,
  *			wp_generate_attachment_metadata, update_post_meta, restore_current_blog
  * @param   $post_id ID of the post
  * @param   $post Post object
  * @return  void
  */
 public function save_post($post_id, $post = NULL)
 {
     // We're only interested in published posts at this time
     if (!in_array($post->post_status, array('publish', 'draft', 'private'))) {
         return;
     }
     // Avoid recursion:
     // wp_insert_post() invokes the save_post hook, so we have to make sure
     // the loop below is only entered once per save action. Therefore we save
     // the source_blog in a static class variable. If it is already set we
     // know the loop has already been entered and we can exit the save action.
     if (NULL === self::$source_blog) {
         self::$source_blog = get_current_blog_id();
     } else {
         return;
     }
     // If checkbox is not checked, return
     if (!isset($_POST['translate_this_post'])) {
         return;
     }
     // Get the post
     $postdata = get_post($post_id, ARRAY_A);
     $post_meta = $this->get_post_meta_to_transfer($post_id);
     // Apply a filter here so modules can play around
     // with the postdata before it is processed.
     $postdata = apply_filters('mlp_pre_save_postdata', $postdata);
     $post_meta = apply_filters('mlp_pre_save_post_meta', $post_meta);
     // If there is no filter hooked into this saving method, then we
     // will exclude all post types other that "post" and "page".
     // @TODO: improve this logic :/
     // @TODO: create a whitelist for allowed post types, incl. apply_filters() ?
     if (!has_filter('mlp_pre_save_postdata')) {
         if ('post' != $postdata['post_type'] && 'page' != $postdata['post_type']) {
             return;
         }
     }
     // When the filter returns FALSE, we'll stop here
     if (FALSE == $postdata || !is_array($postdata)) {
         return;
     }
     $linked = mlp_get_linked_elements($post_id);
     // We already linked this element?
     if (0 !== count($linked)) {
         return;
     }
     $this->set_source_id($post_id);
     $file = '';
     // Check for thumbnail
     if (current_theme_supports('post-thumbnails')) {
         $thumb_id = get_post_thumbnail_id($post_id);
         if (0 < $thumb_id) {
             $path = wp_upload_dir();
             $file = get_post_meta($thumb_id, '_wp_attached_file', true);
             $fileinfo = pathinfo($file);
         }
     }
     // Create the post array
     $newpost = array('post_title' => $postdata['post_title'], 'post_content' => $postdata['post_content'], 'post_status' => 'draft', 'post_author' => $postdata['post_author'], 'post_excerpt' => $postdata['post_excerpt'], 'post_date' => $postdata['post_date'], 'post_type' => $postdata['post_type']);
     $blogs = mlp_get_available_languages();
     if (empty($blogs)) {
         return;
     }
     // Load Page Parents
     $parent_elements = array();
     if ('page' == $postdata['post_type'] && 0 < $postdata['post_parent']) {
         $parent_elements = mlp_get_linked_elements($postdata['post_parent']);
     }
     // Create a copy of the item for every related blog
     foreach ($blogs as $blogid => $blogname) {
         if ($blogid != self::$source_blog) {
             switch_to_blog($blogid);
             // Set the linked parent page
             if (0 < count($parent_elements) && 0 < $parent_elements[$blogid]) {
                 $newpost['post_parent'] = $parent_elements[$blogid];
             }
             // use filter to change postdata for every blog
             $newpost = apply_filters('mlp_pre_insert_post', $newpost);
             // Insert remote blog post
             $remote_post_id = wp_insert_post($newpost);
             if (!empty($post_meta)) {
                 $this->update_remote_post_meta($remote_post_id, $post_meta);
             }
             if ('' != $file) {
                 // thumbfile exists
                 include_once ABSPATH . 'wp-admin/includes/image.php';
                 //including the attachment function
                 if (0 < count($fileinfo)) {
                     $filedir = wp_upload_dir();
                     $filename = wp_unique_filename($filedir['path'], $fileinfo['basename']);
                     $copy = copy($path['basedir'] . '/' . $file, $filedir['path'] . '/' . $filename);
                     if ($copy) {
                         unset($postdata['ID']);
                         $wp_filetype = wp_check_filetype($filedir['url'] . '/' . $filename);
                         //get the file type
                         $attachment = array('post_mime_type' => $wp_filetype['type'], 'guid' => $filedir['url'] . '/' . $filename, 'post_parent' => $remote_post_id, 'post_title' => '', 'post_excerpt' => '', 'post_author' => $postdata['post_author'], 'post_content' => '');
                         //insert the image
                         $attach_id = wp_insert_attachment($attachment, $filedir['path'] . '/' . $filename);
                         if (!is_wp_error($attach_id)) {
                             wp_update_attachment_metadata($attach_id, wp_generate_attachment_metadata($attach_id, $filedir['path'] . '/' . $filename));
                             set_post_thumbnail($remote_post_id, $attach_id);
                         }
                         // update the image data
                     }
                 }
             }
             $this->set_linked_element($remote_post_id);
             restore_current_blog();
         }
     }
 }
 /**
  * Determine the current module state (on/off).
  *
  * Required parameters:
  *  - display_name : name to display in the modules manager
  *  - slug : must correspond with the filename, i.e. slug 'my-module' must be of file my-module.php
  *
  * Optional parametes:
  *  - deactivation : array containing classname / methodname for deactivation.
  *
  * @access	private
  * @since	0.1
  * @return FALSE | if turned off
  */
 private function module_init()
 {
     // Check module state
     $module_init = array('display_name' => 'Multilingual Press Advanced Translator', 'slug' => 'class-' . __CLASS__);
     if ('off' === parent::get_module_state($module_init)) {
         return FALSE;
     }
 }