HEX
Server: nginx/1.27.1
System: Linux in-4 5.15.0-131-generic #141-Ubuntu SMP Fri Jan 10 21:18:28 UTC 2025 x86_64
User: ilikadirect (1186)
PHP: 7.4.33
Disabled: exec,passthru,shell_exec,system,proc_open,popen,parse_ini_file,show_source
Upload Files
File: /storage/v6964/testingff/public_html/fdfctr/wp-content/plugins/ldd-directory-lite/import-lddbd.php
<?php
/**
 * The ldd_directory_lite_import_from_plugin class is for the purpose of upgrading from LDD Business Directory
 * to the new LDD Directory Lite plugin. The general outline of this class came from studying WP_Import to learn how
 * it handled itself when encountering large amounts of data... my original attempt was running out of memory far
 * too easily. Lots'o'fun this one was.
 *
 * @package   ldd_directory_lite
 * @author    LDD Web Design <info@lddwebdesign.com>
 * @license   GPL-2.0+
 * @link      http://lddwebdesign.com
 * @copyright 2014 LDD Consulting, Inc
 */

if (!defined('WPINC'))
    die;

global $wpdb;

define('UPFROM_MAIN_TABLE', $wpdb->prefix . 'lddbusinessdirectory');
define('UPFROM_DOC_TABLE', $wpdb->prefix . 'lddbusinessdirectory_docs');
define('UPFROM_CAT_TABLE', $wpdb->prefix . 'lddbusinessdirectory_cats');


/**
 * The class responsible for setting up and running an upgrade. Imports all data and regenerates it as
 * custom post types and taxonomies. No data should be removed by this process, there will be a clean up tool
 * introduced at a later time.
 *
 * @since 0.5.4
 */
class ldd_directory_lite_import_from_plugin {

    // The data collected for the import
    public $posts = array();
    public $authors = array();
    public $terms = array();

    // ID maps for use between methods
    public $term_map = array();
    public $author_map = array();
    public $post_map = array();
    public $document_map = array();


    /**
     * Main controller class, when our object is created this directs the procession.
     */
    public function __construct() {
        add_action('admin_menu', array($this, 'add_page'));
        add_action('admin_head', array($this, 'hide_page'));
    }


    /**
     * Register the page that we'll use to display the whole process
     */
    public function add_page() {
        add_dashboard_page(esc_html_e('Running Import for LDD Business Directory', 'ldd-directory-lite'), __('LDD Import', 'ldd-directory-lite'), 'manage_options', 'lddlite-import', array(
            $this,
            'import'
        ));
    }

    /**
     * Don't show the registered page on the menu
     */
    public function hide_page() {
        remove_submenu_page('index.php', 'lddlite-import');
    }


    /**
     * Handles the sequence of events for upgrading/importing from the LDD Business Directory plugin
     */
    public function import() {

        ?>
        <div class="wrap">
            <h2><?php esc_html_e('Importing content from LDD Business Directory', 'ldd-directory-lite'); ?></h2>
            <?php

            set_time_limit(0);

            $this->start();

            $this->import_terms();
            $this->import_authors();
            $this->import_posts();
            $this->import_meta();
            $this->import_logo();
            $this->import_files();

            $this->end();

            ?>
        </div>
    <?php
    }


    /**
     * Set up our environment for the upgrade, and collect all information we'll need to get going.
     */
    public function start() {
        global $wpdb;

        wp_defer_term_counting(true);

        echo '<p>' . esc_html_e('Collecting data from original plugin...', 'ldd-directory-lite');
        $this->_get_terms();
        $this->_get_posts();
        echo ' ' . esc_html_e('done.', 'ldd-directory-lite') . '<p>';

        do_action('ldl_import_start');
    }

    /**
     * Pull all the categories out and prep them for import
     */
    private function _get_terms() {
        global $wpdb;

        $query = sprintf("
                SELECT id, name
                FROM `%s`
            ", UPFROM_CAT_TABLE);
        $results = $wpdb->get_results($query);

        if (!empty($results)) {
            foreach ($results as $cat) {
                $this->terms[ $cat->id ] = $cat->name;
            }
        }

    }

    /**
     * Collect our listings and populate the authors array at the same time to save queries.
     */
    private function _get_posts() {
        global $wpdb;

        $query = sprintf("
                SELECT createDate, name, description, categories, address_street, address_city, address_state, address_zip,
                       address_country, phone, fax, email, contact, url, facebook, twitter, linkedin, promoDescription,
                       logo, login, password, approved, other_info
                FROM `%s`
            ", UPFROM_MAIN_TABLE);
        $results = $wpdb->get_results($query);

        foreach ($results as $row) {
            $hash = hash('md5', $row->createDate . $row->name);
            $this->authors[ $hash ] = array(
                'login' => $row->login,
                'email' => $row->email,
            );
        }

        if (!empty($results))
            $this->posts = $results;

    }

    /**
     * Create all custom category terms from the old business directory table.
     * This skips any terms that already exist, but creates a complete map for use elsewhere.
     */
    public function import_terms() {

        $this->terms = apply_filters('ldl_import_terms', $this->terms);

        // Nothing to do
        if (empty($this->terms))
            return;

        foreach ($this->terms as $old_id => $term) {

            $term_id = term_exists($term, LDDLITE_TAX_CAT);
            if (!$term_id) {
                $term_id = wp_insert_term($term, LDDLITE_TAX_CAT);
                // Discard errors, and don't add this to the map
                if (is_wp_error($term_id)) {
                    printf(esc_html_e('Failed to import category %s', 'ldd-directory-lite'), esc_html($term));
                    echo esc_html(': ' . $term_id->get_error_message() . '<br>');
                }
            }

            $this->term_map[ $old_id ] = is_array($term_id) ? $term_id['term_id'] : $term_id;

        }

        printf('<p>' . esc_html_e('Added %d listing categories.', 'ldd-directory-lite') . '</p>', count($this->term_map));
        unset($this->terms);

    }

    /**
     * Create all the author accounts using built in WordPress logins.
     * Data for this process can't be trusted whatsoever, and passwords aren't reused due to the insecure
     * way they had been previously stored.
     */
    public function import_authors() {

        $this->authors = apply_filters('ldl_import_authors', $this->authors);

        if (empty($this->authors))
            return;

        // Authors are attributed to their posts by the hash, this needs to be recycled in the map
        foreach ($this->authors as $hash => $row) {

            // If their original username was an email, use the local part as their new username
            $has_at = strpos($row['login'], '@');
            if (false === $has_at) {
                $author_login = sanitize_user($row['login'], 1);
            } else if (false !== $has_at && 0 === strpos(strtolower($row['login']), 'admin')) {
                // it's not entirely uncommon for an email to begin with "admin", use the domain part instead
                $author_login = sanitize_user(substr($row['login'], (strpos($row['login'], '@') + 1)), 1);
            } else {
                $author_login = sanitize_user(substr($row['login'], 0, strpos($row['login'], '@')), 1);
            }

            $author_email = (empty($row['email']) && false !== $has_at) ? $row['login'] : $row['email'];

            $author_id = username_exists($author_login);
            if (!$author_id) {
                $author_id = email_exists($author_email);
                if (!$author_id) {
                    // Force users to reset accounts through "lost password"
                    $author_id = wp_create_user($author_login, wp_generate_password(), $author_email);
                    if (is_wp_error($author_id)) {
                        printf(__('Failed to import owner %s', 'ldd-directory-lite'), esc_html($author_login));
                        echo esc_html(': ' . $author_id->get_error_message() . '<br>');
                    }
                }
            }

            $this->author_map[ $hash ] = (!$author_id || 1 == $author_id) ? (int) get_current_user_id() : $author_id;

        }

        printf('<p>' . esc_html_e('Added %d listing owners.', 'ldd-directory-lite') . '</p>', count($this->author_map));
        unset($this->authors);

    }

    /**
     * Create posts from the imported listing data.
     * Checking for the posts existence should hopefully negate the need to put the site into maintenance mode,
     * which seems to be too disruptive.
     */
    public function import_posts() {
        $this->posts = apply_filters('ldl_import_posts', $this->posts);

        if (!function_exists('post_exists'))
            require_once(ABSPATH . 'wp-admin/includes/post.php');

        // Get this outside the loop in case we need it
        $current_user_id = get_current_user_id();

        foreach ($this->posts as $post) {

            $post_status = ('true' == $post->approved) ? 'publish' : 'pending';
            $hash = md5($post->createDate . $post->name);

            $new = array(
                'post_content' => $post->description,
                'post_title'   => $post->name,
                'post_status'  => $post_status,
                'post_type'    => LDDLITE_POST_TYPE,
                'post_date'    => $post->createDate,
            );

            // Don't generate duplicates, please!
            $post_id = post_exists($new['post_title'], '', $new['post_date']);

            if ($post_id) {
                printf('<p><strong>' . esc_html_e('Listing already exists', 'ldd-directory-lite') . ':</strong> %s</p>', esc_html($new['post_title']));
            } else {

                $author_id = $this->author_map[ $hash ];
                $term_ids = array();

                // Failsafe
                if (!get_user_by('id', $author_id))
                    $author_id = $current_user_id;

                $new['post_author'] = $author_id;

                $post_id = wp_insert_post($new);

                if (is_wp_error($post_id)) {
                    printf(esc_html_e('Failed to add listing %s', 'ldd-directory-lite'), esc_html($new['post_title']));
                    echo esc_html(': ' . $post_id->get_error_message() . '<br>');
                } else {

                    // Get list of associated terms and assign them
                    if (!empty($post->categories)) {
                        $terms = explode(',', str_replace('x', '', $post->categories));

                        foreach ($terms as $old_id) {
                            if (empty($old_id))
                                continue;
                            // We're not checking if the term exists here and trusting that it will only be mapped
                            // if it was successfully created.
                            if (array_key_exists($old_id, $this->term_map))
                                $term_ids[] = $this->term_map[ $old_id ];
                        }

                        wp_set_post_terms($post_id, $term_ids, LDDLITE_TAX_CAT);

                    }

                }

                // Only map newly created posts, so existing posts are skipped during $this->import_meta()
                // This should stay here...
                $this->post_map[ $hash ] = $post_id;
                printf(esc_html_e('Added listing', 'ldd-directory-lite') . ': <em>%s</em><br>', esc_html($new['post_title']));

            }
            // ...and not be moved here.

        }

        printf('<p>' . esc_html_e('Added a total of %d new listings.', 'ldd-directory-lite') . '</p>', count($this->post_map));

    }

    /**
     * Using $this->post_map the next stage is to add all the post meta to each listing. Additionally handles
     * renaming the logo file and adding it as the post thumbnail.
     */
    public function import_meta() {

        echo '<p>' . esc_html_e('Adding listing meta information...', 'ldd-directory-lite');

        foreach ($this->posts as $post) {

            // Do we need to generate meta for this post?
            $hash = md5($post->createDate . $post->name);
            if (!array_key_exists($hash, $this->post_map))
                continue;

            $post_id = $this->post_map[ $hash ];

            $post_meta = array(
                'country'     => $post->address_country,
                'post_code'   => $post->address_zip,
                'address_one' => $post->address_street,
                'city' 		  => $post->address_city,
				'state'		  => (empty($post->address_state) ? '' : ' ' . $post->address_state),
                'geo'         => array(
                    'lat'       => '',
                    'lng'       => '',
                ),
            );

            if (!empty($post->email))
                $post_meta['contact_email'] = $post->email;
            if (!empty($post->phone))
                $post_meta['contact_phone'] = $post->phone;
            if (!empty($post->promoDescription))
                $post_meta['promotion'] = $post->promoDescription;
            if (!empty($post->other_info))
                $post_meta['other'] = $post->other_info;

            if (!empty($post->url))
                $post_meta['url_website'] = esc_url_raw($post->url);
            if (!empty($post->facebook))
                $post_meta['url_facebook'] = ldl_force_scheme($post->facebook);
            if (!empty($post->linkedin))
                $post_meta['url_linkedin'] = ldl_force_scheme($post->linkedin);
            if (!empty($post->twitter))
                $post_meta['url_twitter'] = ldl_sanitize_twitter($post->twitter);

            foreach ($post_meta as $key => $value) {
                add_post_meta($post_id, ldl_pfx($key), $value);
            }

        }

        echo ' ' . esc_html_e('done.', 'ldd-directory-lite') . '<p>';

    }

    /**
     * Using $this->post_map the next stage is to add all the post meta to each listing. Additionally handles
     * renaming the logo file and adding it as the post thumbnail.
     */
    public function import_logo() {

        echo '<p>' . esc_html_e("Importing logo's...", 'ldd-directory-lite');

        if (!function_exists('wp_generate_attachment_metadata'))
            require_once(ABSPATH . 'wp-admin/includes/image.php');

        $wp_upload_dir = wp_upload_dir();

        $creds = request_filesystem_credentials('');
        if (WP_Filesystem($creds)) {
            global $wp_filesystem;
        } else {
            return;
        }

        foreach ($this->posts as $post) {

            // Do we need to generate meta for this post?
            $hash = md5($post->createDate . $post->name);
            if (!array_key_exists($hash, $this->post_map))
                continue;

            if ($post->logo && file_exists($wp_upload_dir['basedir'] . '/' . $post->logo)) {

                $post_id = $this->post_map[ $hash ];

                $old = $wp_upload_dir['basedir'] . '/' . $post->logo;
                $new = $wp_upload_dir['path'] . '/' . basename($post->logo);

                // Don't delete, in case users want to roll back
                // @todo When there's a stable release, add a utility to offer clean-up
                if ($wp_filesystem->copy($old, $new)) {

                    $filetype = wp_check_filetype($new);
                    $attachment = array(
                        'guid'           => $wp_upload_dir['url'] . '/' . basename($new),
                        'post_mime_type' => $filetype['type'],
                        'post_title'     => sanitize_title(substr(basename($new), 0, -4)),
                        'post_content'   => '',
                        'post_status'    => 'inherit'
                    );

                    $attached = wp_insert_attachment($attachment, $new, $post_id);

                    if ($attached) {
                        $attach_data = wp_generate_attachment_metadata($attached, $new);
                        wp_update_attachment_metadata($attached, $attach_data);

                        set_post_thumbnail($post_id, $attached);
                    }

                }

            }

        }

        echo ' ' . esc_html_e('done.', 'ldd-directory-lite') . '<p>';

        unset($this->posts);
    }

    /**
     * Bring any attached files over and make sure they're associated with the proper post.
     * It seems the original plugin borked a few uploads and deleted file extensions. I can't justify the extra
     * cycles to try and save these files when this process is already pretty CPU intensive to begin with. Sorry!
     */
    public function import_files() {

        echo '<p>' . esc_html_e('Updating file attachments...', 'ldd-directory-lite');

        $wp_upload_dir = wp_upload_dir();
        $uploads_base = $wp_upload_dir['basedir'] . '/directory-lite';

        if (!function_exists('request_filesystem_credentials'))
            require_once(ABSPATH . 'wp-admin/includes/file.php');

        $creds = request_filesystem_credentials('');
        if (WP_Filesystem($creds)) {
            global $wp_filesystem;
        } else {
            return; // No use going further if we don't have a working base directory
        }

        if (!file_exists($uploads_base)) {
            if (!$wp_filesystem->mkdir($uploads_base)) {
                return;
            }
        }

        foreach ($this->document_map as $hash => $doc) {

            if (!array_key_exists($hash, $this->post_map))
                continue;

            $old = $wp_upload_dir['basedir'] . '/' . $doc['path'];

            if (!file_exists($old))
                continue;


            $filetype = wp_check_filetype($old);

            // It's not worth the cycles to try and save files that were corrupted by the Business Directory upload
            if (!$filetype['type'])
                continue;


            $new = $uploads_base . '/' . sanitize_file_name(basename($doc['path']));

            // Say it with me, copy, don't move.
            if (!$wp_filesystem->copy($old, $new)) {

                $post_id = $this->post_map[ $hash ];

                $attachment = array(
                    'guid'           => $wp_upload_dir['url'] . '/' . sanitize_file_name(basename($doc['path'])),
                    'post_mime_type' => $filetype['type'],
                    'post_title'     => empty($doc['title']) ? sanitize_title(basename($doc['path'])) : $doc['title'],
                    'post_content'   => empty($doc['desc']) ? '' : $doc['desc'],
                    'post_status'    => 'inherit'
                );

                $attached = wp_insert_attachment($attachment, $new, $post_id);

                if ($attached) {
                    $attach_data = wp_generate_attachment_metadata($attached, $new);
                    wp_update_attachment_metadata($attached, $attach_data);
                }

            }

        }

        echo ' ' . esc_html_e('done.', 'ldd-directory-lite') . '<p>';

        unset($this->document_map);

    }

    /**
     * Run clean up after the import has completed.
     */
    public function end() {

        wp_cache_flush();
        wp_defer_term_counting(false);

        // Attempt to disable the old plugin
        if (!function_exists('deactivate_plugins'))
            require_once(ABSPATH . 'wp-admin/includes/plugin.php');

        deactivate_plugins('ldd-business-directory/lddbd_core.php', true);

        do_action('ldl_import_end');

        echo '<p><strong>' . esc_html_e('All done!', 'ldd-directory-lite') . '</strong><br>' . esc_html_e('Passwords have been reset for security purposes, please notify your users!', 'ldd-directory-lite') . '</p>';
        echo '<p><a href="' . admin_url() . '">' . esc_html_e('Return to WordPress Dashboard', 'ldd-directory-lite') . '</a>' . ' | ';
        echo '<a href="' . admin_url('edit.php?post_type=' . LDDLITE_POST_TYPE . '&page=lddlite-settings') . '">' . esc_html_e('Directory Settings', 'ldd-directory-lite') . '</a></p>';

        update_option('lddlite_imported_from_original', true);

    }

    /**
     * Documents are not currently in use with the Lite plugin, but will be soon. Don't leave them behind.
     */
    private function _get_files_list() {
        global $wpdb;

        // To hash by way of query, or via hash()? Does it matter? Obviously enough to write a comment about it...
        $query = sprintf("
                SELECT docs.doc_path, docs.doc_name, docs.doc_description, md5( CONCAT( post.createDate, post.name ) ) AS hash
                FROM `%s` AS docs
                  LEFT JOIN `%s` AS post
                  ON docs.bus_id = post.id
          ", UPFROM_DOC_TABLE, UPFROM_MAIN_TABLE);
        $results = $wpdb->get_results($query);

        foreach ($results as $row) {
            $this->document_map[ $row->hash ] = array(
                'path'  => $row->doc_path,
                'title' => $row->doc_name,
                'desc'  => $row->description,
            );
        }

    }

}


/**
 * This class is derived wholly or in part or mostly from the ajax-notification github repository. Thanks Tom!
 *
 * @since 0.5.4
 * @link  https://github.com/tommcfarlin/ajax-notification Tom's Ajax-Notification
 */
class ldd_directory_lite_import_from_notice {

    public function __construct() {

        add_action('admin_head', array($this, 'add_scripts'));

        // Don't append this notice on the actual upgrade page
        $curr = isset($_GET['page']) ? sanitize_text_field($_GET['page']) : '';
        if (false == get_option('lddlite_imported_from_original') && 'lddlite-import' != $curr) {
            add_action('admin_notices', array($this, 'display_notice'));
        }

    }

    public function add_scripts() {
		?>
        <script>(function(e){"use strict";e(function(){e("#dismiss-import-notice").length>0&&e("#dismiss-import-notice").click(function(t){t.preventDefault();e.post(ajaxurl,{action:"hide_import_notice",nonce:e.trim(e("#lddlite-import-nonce").text())},function(t){"1"===t?e("#directory-upgrade-notification").fadeOut("slow"):e("#directory-upgrade-notification").removeClass("updated").addClass("error")})})})})(jQuery);</script>
        <?php
    }

    public function display_notice() {
        $screen = get_current_screen();

        if (LDDLITE_POST_TYPE != $screen->post_type)
            return;

        $html = '<div id="directory-upgrade-notification" class="updated">';
        $html .= '<p style="font-size:120%;font-weight:700;">' . __('Existing data has been detected!', 'ldd-directory-lite') . '</p>';
        $html .= '<p style="font-weight:700;">' . __('It looks like you have data from the LDD Business Directory plugin! Would you like to import this?', 'ldd-directory-lite');
        $html .= ' &nbsp; <a href="' . admin_url('admin.php?page=lddlite-import') . '" class="button">' . __('Import Data.', 'ldd-directory-lite') . '</a>';
        $html .= '<p>' . __('If you do not wish to import your existing data, you can', 'ldd-directory-lite') . ' <a href="javascript:;" id="dismiss-import-notice">' . __('dismiss', 'ldd-directory-lite') . '</a> ' . __('this notice.', 'ldd-directory-lite') . '</p>';
        $html .= '<span id="lddlite-import-nonce" class="hidden">' . wp_create_nonce('lddlite-import-nonce') . '</span>';
        $html .= '</div>';

        echo wp_kses_post($html);
    }

}

new ldd_directory_lite_import_from_plugin;
new ldd_directory_lite_import_from_notice;