<?php

/*
  Plugin Name: Atelier-111 - Personnalisation
  Plugin URI: http://www.atelier-111.fr
  Description: Plugin permettant la personnalisation du style et des polices sur les sites d'Atelier-111
  Version: 2.7.1
  Author: PONCET Romain
  Author URI: http://www.atelier-111.fr
  License: GPL2
 */

if(!defined('GITHUB_TOKEN')){
    define ('GITHUB_TOKEN', '');
}

class personnalisationAtelier111 {

    // Tableau des extension autorisées en php TypeMime => extension
    private $arrExtension = array('image/jpeg' => 'jpg',
        'image/jpeg' => 'jpeg',
        'image/png' => 'png');
    // Tableau de correspondance nomInput => nomFichier
    private $fileName = array('file_header' => 'logo_header',
        'file_header_small' => 'logo_header_small',
        'file_footer' => 'logo_footer',
        'file_footer_small' => 'logo_footer_small',
        'file_inverse' => 'logo_inverse',
        'file_image_defaut' => 'image_defaut');

    const listePolices = array(
        'BioRhyme' => array("font" => "'BioRhyme', serif", "link" => "BioRhyme:400,700"),
        'Droid Serif' => array("font" => "'Droid Serif', serif", "link" => "Droid+Serif:400,400i,700,700i"),
        'Lato' => array("font" => "'Lato', sans-serif", "link" => "Lato:300italic,300,700,700italic"),
        'Noto Sans' => array("font" => "'Noto Sans', sans-serif", "link" => "Noto+Sans:400,400i,700,700i"),
        'Open Sans' => array("font" => "'Open Sans', sans-serif", "link" => "Open+Sans:400,400i,700,700i"),
        'Podkova' => array("font" => "'Podkova', serif", "link" => "Podkova:400,700"),
        'PT Serif' => array("font" => "'PT Serif', serif", "link" => "PT+Serif:400,400i,700,700i"),
        'Roboto Slab' => array("font" => "'Roboto Slab', serif", "link" => "Roboto+Slab:400,700"),
        'Yanone Kaffeesatz' => array("font" => "'Yanone Kaffeesatz', sans-serif", "link" => "Yanone+Kaffeesatz:400,700"),
    );

    // Nombre de couleurs gérées pour le site
    private $nbCouleurSite = 5;
    // Nombre de couleurs de polices gérées pour le site
    private $nbCouleurPolices = 5;
    // Nombre de polices gérées pour le site
    private $nbPolices = 1;
    private $slug; // plugin slug
    private $pluginData; // plugin data
    private $username; // GitHub username
    private $repo; // GitHub repo name
    private $pluginFile; // __FILE__ of our plugin
    private $githubAPIResult; // holds data from GitHub
    private $accessToken; // GitHub private repo token

    public function __construct() {


        register_activation_hook(__FILE__, array('PersonnalisationAtelier111_Plugin', 'install'));
        register_uninstall_hook(__FILE__, array('PersonnalisationAtelier111_Plugin', 'uninstall'));

        if($accessToken != '') {
            add_filter("pre_set_site_transient_update_plugins", array($this, "setTransitent"));
            add_filter("plugins_api", array($this, "setPluginInfo"), 10, 3);
            add_filter("upgrader_post_install", array($this, "postInstall"), 10, 3);
            $this->pluginFile = $pluginFile;
            $this->username = $gitHubUsername;
            $this->repo = $gitHubProjectName;
            $this->accessToken = $accessToken;
        }

        // Déclenchement de l'action d'ajout du menu
        add_action('admin_menu', array($this, 'addAdminMenu'));
        add_action('wp_loaded', array($this, 'savePersonnalisation'));

        if (isset($_GET['page']) && ($_GET['page'] == 'a111-personnalisation' || $_GET['page'] == 'a111-personnalisation')) {
            add_action('init', array($this, 'init'), 1);
            add_filter('wp_title', array($this, 'modify_page_title'), 20);
        }
    }

    // Get information regarding our plugin from WordPress
    private function initPluginData() {
        $this->slug = plugin_basename($this->pluginFile);
        $this->pluginData = get_plugin_data($this->pluginFile);
    }

    // Get information regarding our plugin from GitHub
    private function getRepoReleaseInfo() {
        // Only do this once
        if (!empty($this->githubAPIResult)) {
            return;
        }
        // Query the GitHub API
        $url = "https://api.github.com/repos/{$this->username}/{$this->repo}/releases";
        // We need the access token for private repos
        if (!empty($this->accessToken)) {
            $url = add_query_arg(array("access_token" => $this->accessToken), $url);
        }
        // Get the results
        $this->githubAPIResult = wp_remote_retrieve_body(wp_remote_get($url));
        if (!empty($this->githubAPIResult)) {
            $this->githubAPIResult = @json_decode($this->githubAPIResult);
        }
        // Use only the latest release
        if (is_array($this->githubAPIResult)) {
            $this->githubAPIResult = $this->githubAPIResult[0];
        }
    }

    // Push in plugin version information to get the update notification
    public function setTransitent($transient) {
        // If we have checked the plugin data before, don't re-check
        if (empty($transient->checked)) {
            return $transient;
        }
        // Get plugin & GitHub release information
        $this->initPluginData();
        $this->getRepoReleaseInfo();
        // Check the versions if we need to do an update
        $doUpdate = version_compare($this->githubAPIResult->tag_name, $transient->checked[$this->slug]);
        // Update the transient to include our updated plugin data
        if ($doUpdate == 1) {
            $package = $this->githubAPIResult->zipball_url;
            // Include the access token for private GitHub repos
            if (!empty($this->accessToken)) {
                $package = add_query_arg(array("access_token" => $this->accessToken), $package);
            }
            $obj = new stdClass();
            $obj->slug = $this->slug;
            $obj->new_version = $this->githubAPIResult->tag_name;
            $obj->url = $this->pluginData["PluginURI"];
            $obj->package = $package;
            $transient->response[$this->slug] = $obj;
        }
        return $transient;
    }

    // Push in plugin version information to display in the details lightbox
    public function setPluginInfo($false, $action, $response) {
        // Get plugin & GitHub release information
        $this->initPluginData();
        $this->getRepoReleaseInfo();
        // If nothing is found, do nothing
        if (empty($response->slug) || $response->slug != $this->slug) {
            return false;
        }
        // Add our plugin information
        $response->last_updated = $this->githubAPIResult->published_at;
        $response->slug = $this->slug;
        $response->plugin_name = $this->pluginData["Name"];
        $response->version = $this->githubAPIResult->tag_name;
        $response->author = $this->pluginData["AuthorName"];
        $response->homepage = $this->pluginData["PluginURI"];
        $response->name = $this->pluginData["Name"];
        // This is our release download zip file
        $downloadLink = $this->githubAPIResult->zipball_url;
        // Include the access token for private GitHub repos
        if (!empty($this->accessToken)) {
            $downloadLink = add_query_arg(
                    array("access_token" => $this->accessToken), $downloadLink
            );
        }
        $response->download_link = $downloadLink;
        // We're going to parse the GitHub markdown release notes, include the parser
        require_once( plugin_dir_path(__FILE__) . "Parsedown.php" );
        // Create tabs in the lightbox
        $response->sections = array(
            'description' => $this->pluginData["Description"],
            'changelog' => class_exists("Parsedown") ? Parsedown::instance()->parse($this->githubAPIResult->body) : $this->githubAPIResult->body
        );
        // Gets the required version of WP if available
        $matches = null;
        preg_match("/requires:\s([\d\.]+)/i", $this->githubAPIResult->body, $matches);
        if (!empty($matches)) {
            if (is_array($matches)) {
                if (count($matches) > 1) {
                    $response->requires = $matches[1];
                }
            }
        }
        // Gets the tested version of WP if available
        $matches = null;
        preg_match("/tested:\s([\d\.]+)/i", $this->githubAPIResult->body, $matches);
        if (!empty($matches)) {
            if (is_array($matches)) {
                if (count($matches) > 1) {
                    $response->tested = $matches[1];
                }
            }
        }
        return $response;
    }

    // Perform additional actions to successfully install our plugin
    public function postInstall($true, $hook_extra, $result) {
        // Get plugin information
        $this->initPluginData();
        // Remember if our plugin was previously activated
        $wasActivated = is_plugin_active($this->slug);
        // Since we are hosted in GitHub, our plugin folder would have a dirname of
        // reponame-tagname change it to our original one:
        global $wp_filesystem;
        $pluginFolder = WP_PLUGIN_DIR . DIRECTORY_SEPARATOR . dirname($this->slug);
        $wp_filesystem->move($result['destination'], $pluginFolder);
        $result['destination'] = $pluginFolder;
        // Re-activate plugin if needed
        if ($wasActivated) {
            $activate = activate_plugin($this->slug);
        }
        return $result;
    }

    /**
     * Perform check before installation starts.
     *
     * @param  boolean $true
     * @param  array   $args
     * @return null
     */
    public function preInstall($true, $args) {
        // Get plugin information
        $this->initPluginData();

        // Check if the plugin was installed before...
        $this->pluginActivated = is_plugin_active($this->slug);
    }

    public static function init() {
        wp_enqueue_script('jquery');

        wp_register_style('bootstrapMinCss', plugins_url() . '/personnalisationAtelier111/css/bootstrap.min.css');
        wp_enqueue_style('bootstrapMinCss');

        wp_register_style('personnalisationAtelier111', plugins_url() . '/personnalisationAtelier111/css/personnalisationAtelier111.css');
        wp_enqueue_style('personnalisationAtelier111');

        wp_register_script('bootstrapMinJs', plugins_url() . '/personnalisationAtelier111/js/bootstrap.min.js');
        wp_enqueue_script('bootstrapMinJs');

        wp_register_script('personnalisationAtelier111Js', plugins_url() . '/personnalisationAtelier111/js/parametresA111.js');
        wp_enqueue_script('personnalisationAtelier111Js');

        wp_register_script('colorpickerJs', plugins_url() . '/personnalisationAtelier111/js/bootstrap-colorpicker.min.js');
        wp_enqueue_script('colorpickerJs');
        wp_register_style('colorpickerCss', plugins_url() . '/personnalisationAtelier111/css/bootstrap-colorpicker.min.css');
        wp_enqueue_style('colorpickerCss');
    }

    /**
     * Création de la table de paramètres
     *
     */
    public static function install() {

        global $wpdb;

        $wpdb->query("CREATE TABLE IF NOT EXISTS {$wpdb->prefix}a111_parametres (type VARCHAR(16) PRIMARY KEY, valeur VARCHAR(64), contenu VARCHAR (255), description TEXT);");
        $wpdb->query("ALTER TABLE {$wpdb->prefix}a111_parametres DROP PRIMARY KEY, ADD PRIMARY KEY( `type`, `valeur`);");
    }

    /**
     * @param $title Le titre de la page
     * @return string
     */
    public function modify_page_title($title) {
        return $title . ' | Personnalisation ';
    }

    /**
     * Creation du menu principal
     */
    public function addAdminMenu() {
        add_menu_page(
                "Personnalisation-Atelier-111", // le titre de la page
                'Personnalisation-Atelier-111', // le nom de la page dans le menu d'admin
                'administrator', // le rôle d'utilisateur requis pour voir cette page
                'a111-personnalisation', // un identifiant unique de la page
                array($this, 'a111PersonnalisationForm'), /* ,// le nom d'une fonction qui affichera la page
                  'dashicons-email-alt',
                  71 // positions dans le menu */ 'dashicons-admin-appearance'
        );
    }

    /**
     * Fonction qui appelle le formulaire de personnalisation
     */
    public function a111PersonnalisationForm() {

        include_once plugin_dir_path(__FILE__) . '/formPersonnalisation.php';
    }

    /**
     * Fonction qui enregistre ou modifie la personnalisation
     */
    public function savePersonnalisation() {

        if (!is_admin()) {
            wp_register_style('styleA111', plugins_url() . '/personnalisationAtelier111/styleA111.css');
            wp_enqueue_style('styleA111');
        }

        // Globale pour l'affichage du message
        global $msg;

        // Globale pour l'affichage des couleurs sur le formulaire
        global $gestionCouleurs;

        if ((isset($_POST['uploadLogos']) && !empty($_POST['uploadLogos'])) || (isset($_POST['uploadImageDefaut']) && !empty($_POST['uploadImageDefaut'])) && count($_FILES) > 0) {
            try {

                require_once(ABSPATH . "wp-admin" . '/includes/admin.php' );
                require_once(ABSPATH . "wp-admin" . '/includes/image.php');
                require_once(ABSPATH . "wp-admin" . '/includes/file.php');
                require_once(ABSPATH . "wp-admin" . '/includes/media.php');

                // Changement du chemin de chargement des fichiers
                add_filter('upload_dir', array($this, 'changeUploadDir'), 20, 2);

                $upload_overrides = array('test_form' => false,
                    'mimes' => array(// Formats de fichiers autorisés
                        'jpg|jpeg|jpe' => 'image/jpeg',
                        'png' => 'image/png')
                );
                // On parcourt les fichiers postés
                foreach ($_FILES as $typeFile => $file) {
                    // Vérification si le $file n'est pas issu d'un champ vide
                    if ($file['name'] != '') {
                        // Vérification si le type mime est autorisé
                        if (array_key_exists($file['type'], $this->arrExtension)) {

                            $tabExtension = explode('.', $file['name']);
                            end($tabExtension);

                            // Changement de nom de fichier pour le forcer ex: logo_header.extension
                            if (array_key_exists($typeFile, $this->fileName)) {
                                $file['name'] = $this->fileName[$typeFile] . '.' . strtolower(current($tabExtension));
                            }


                            // Vérification si le fichier existe déjà
                            $uploadDir = wp_upload_dir();
                            if (file_exists($uploadDir['path'] . '/' . $file['name'])) {
                                // Suppression du fichier si existant
                                unlink($uploadDir['path'] . '/' . $file['name']);
                            }

                            $tab = explode('.', $file['name']);
                            foreach (glob($uploadDir['path'] . '/cropped-' . $tab[0] . '*') as $filename) {
                                unlink($filename);
                            }

                            // Chargement du fichier
                            $result = wp_handle_upload($file, array('test_form' => false));

                            // Génération des différentes tailles d'image
                            PersonnalisationAtelier111_Plugin::generateAllImageSize($result['file'], current($tabExtension));

                            if ($result && !isset($result['error'])) {
                                update_option($this->fileName[$typeFile], $file['name']);
                                $msg .= '<div class="alert alert-success" role="alert">Le fichier ' . $file['name'] . ' a été chargé avec succès</div>';
                            } else {
                                throw new Exception('<div class="alert alert-danger" role="alert">Erreur pendant le chargement du fichier ' . $file['name'] . '</div>');
                            }
                        } else {
                            throw new Exception('<div class="alert alert-danger" role="alert">Le fichier ' . $file['name'] . ' est trop volumineux</div>');
                        }
                    }
                }

                // Annulation du changement du chemin de chargement des fichiers
                remove_filter('upload_dir', array($this, 'changeUploadDir'), 20, 2);
            } catch (Exception $e) {
                // echo 'Erreur: '.$e->getMessage()."\n";
                $msg .= $e->getMessage();
            }
        }

        // Si le formulaire de gestion des couleurs a été posté
        if (isset($_POST['gestionCouleurSite']) && !empty($_POST['gestionCouleurSite'])) {

            $arrayCouleur = array();

            $url = plugin_dir_path(__FILE__) . 'styleModele.css';
            $cssContent = file_get_contents($url);
            // Remplissage du tableau avec les couleurs du site
            // Remplacement des balises
            for ($i = 1; $i <= $this->nbCouleurSite; $i++) {
                $arrayCouleur['COULEUR_SITE_' . $i] = $_POST['couleur_site_' . $i];
                $cssContent = str_replace('[COULEUR_SITE_' . $i . ']', $_POST['couleur_site_' . $i], $cssContent);
            }

            // Remplissage du tableau avec les couleurs de police
            // Remplacement des balises
            for ($i = 1; $i <= $this->nbCouleurPolices; $i++) {
                $arrayCouleur['COULEUR_POLICE_' . $i] = $_POST['couleur_police_' . $i];
                $cssContent = str_replace('[COULEUR_POLICE_' . $i . ']', $_POST['couleur_police_' . $i], $cssContent);
            }

            // Remplissage du tableau avec les polices
            // Remplacement des balises
            for ($i = 1; $i <= $this->nbPolices; $i++) {
                $arrayCouleur['POLICE_SITE_' . $i] = $_POST['police_site_' . $i];
                $cssContent = str_replace('[POLICE_SITE_' . $i . ']', self::listePolices[$_POST['police_site_' . $i]]["font"], $cssContent);
            }

            // Stockage dans la globale
            $gestionCouleurs = $arrayCouleur;

            $fileCss = plugin_dir_path(__FILE__) . 'styleA111.css';
            if (file_exists($fileCss)) {
                file_put_contents($fileCss, $cssContent);
            } else {
                $msg .= '<div class="alert alert-danger" role="alert">Une erreur est survenue pendant la mise à jour de la feuille de style</div>';
            }

            if (update_option('personnalisationCouleur', $arrayCouleur)) {
                $msg .= '<div class="alert alert-success" role="alert">Les couleurs ont été mises à jour</div>';
            } else {
                $msg .= '<div class="alert alert-danger" role="alert">Une erreur est survenue pendant la mise à jour des couleurs</div>';
            }
        }
    }

    /**
     * Fonction qui retourne tous les paramètres
     */
    public function getAllParametres() {
        global $wpdb;
        $results = $wpdb->get_results("SELECT * FROM {$wpdb->prefix}a111_parametres", OBJECT);
        return $results;
    }

    /**
     * Fonction qui change le repertoire de chargement des fichiers
     */
    public function changeUploadDir($dirs) {
        return array(
            'path' => $dirs['basedir'] . '/logos',
            'url' => $dirs['baseurl'] . '/logos',
            'subdir' => '/logos',
                ) + $dirs;
    }

    /**
     * Fonction qui génére toutes les tailles d'images définis
     */
    public function generateAllImageSize($path, $ext) {

        if (!empty($ext) && $ext != '') {

            $tabImageSizes = PersonnalisationAtelier111_Plugin::get_image_sizes();

            $defaultImage = getimagesize($path);
            $WIDTH = $defaultImage[0];
            $HEIGHT = $defaultImage[1];
            $dst_file = wp_upload_dir();

            $imageObject = wp_get_image_editor($path);

            if (!is_wp_error($imageObject)) {
                $tab = array();
                $tabName = array();
                foreach ($tabImageSizes as $index => $image) {
                    $name = $index;
                    $width = $image['width'];
                    $height = $image['height'];
                    $crop = $image['crop'];
                    $centre_x = $WIDTH / 2;
                    $centre_y = $HEIGHT / 2;

                    if ($crop == false) {
                        $tab[] = $image;
                        $tabName[] = $name;
                    } else {
                        if (!is_array($crop)) {
                            $src_w = $WIDTH - $width;
                            $src_h = $HEIGHT - $height;
                            if ($src_w > 0 && $src_h > 0) {
                                $newFilePath = wp_crop_image($path, 0, 0, $width, $height, $width, $height, $dst_file);
                                update_option('image_defaut_' . $name, basename($newFilePath));
                            }
                        } else {
                            $src_x = $centre_x - $width / 2;
                            $src_y = $centre_y - $height / 2;
                            if ($src_x > 0 && $src_y > 0) {
                                $newFilePath = wp_crop_image($path, $src_x, $src_y, $WIDTH - $src_x, $HEIGHT - $src_y, $width, $height, $dst_file);
                                update_option('image_defaut_' . $name, basename($newFilePath));
                            }
                        }
                    }
                }
                $arrayImage = $imageObject->multi_resize($tab);
                foreach ($arrayImage as $index => $i) {
                    update_option('image_defaut_' . $tabName[$index], $i['file']);
                }
            }
        }
    }

    public function get_image_sizes() {
        global $_wp_additional_image_sizes;

        $sizes = array();

        foreach (get_intermediate_image_sizes() as $_size) {
            if (in_array($_size, array('thumbnail', 'medium', 'medium_large', 'large'))) {
                $sizes[$_size]['width'] = get_option("{$_size}_size_w");
                $sizes[$_size]['height'] = get_option("{$_size}_size_h");
                $sizes[$_size]['crop'] = (bool) get_option("{$_size}_crop");
            } elseif (isset($_wp_additional_image_sizes[$_size])) {
                $sizes[$_size] = array(
                    'width' => $_wp_additional_image_sizes[$_size]['width'],
                    'height' => $_wp_additional_image_sizes[$_size]['height'],
                    'crop' => $_wp_additional_image_sizes[$_size]['crop'],
                );
            }
        }

        return $sizes;
    }

}
