[ Avaa Bypassed ]




Upload:

Command:

hmhc3928@18.117.71.102: ~ $
<?php

use chdemko\BitArray\BitArray;

/**
 * SegmentPlugin for phplist.
 *
 * This file is a part of SegmentPlugin.
 *
 * SegmentPlugin is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * SegmentPlugin is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * @category  phplist
 *
 * @author    Duncan Cameron
 * @copyright 2014-2017 Duncan Cameron
 * @license   http://www.gnu.org/licenses/gpl.html GNU General Public License, Version 3
 */

/**
 * Plugin class.
 *
 * @category  phplist
 */
class SegmentPlugin extends phplistPlugin
{
    const VERSION_FILE = 'version.txt';
    const GUIDANCE = 'https://resources.phplist.com/plugin/segment#add_segment_conditions';

    private $error_level;
    private $selectedSubscribers = null;
    private $dao;

    /*
     *  Inherited variables
     */
    public $name = 'Segmentation';
    public $authors = 'Duncan Cameron';
    public $description = 'Send to a subset of subscribers using custom conditions';
    public $documentationUrl = 'https://resources.phplist.com/plugin/segment';
    public $settings;

    private function filterEmptyFields(array $conditions)
    {
        return array_filter(
            $conditions,
            function ($c) {
                return $c['field'] !== '';
            }
        );
    }

    private function filterIncompleteConditions(array $conditions)
    {
        return array_filter(
            $conditions,
            function ($c) {
                return $c['field'] !== '' && isset($c['op']);
            }
        );
    }

    private function deleteNotSent($campaign)
    {
        $this->dao->deleteNotSent($campaign);
    }

    private function selectionQueryJoins(array $conditions)
    {
        $cf = new SegmentPlugin_ConditionFactory($this->dao);
        $joins = array();

        foreach ($conditions as $i => $c) {
            $field = $c['field'];

            try {
                $condition = $cf->createCondition($field);
                $joins[] = $condition->joinQuery($c['op'], isset($c['value']) ? $c['value'] : '');
            } catch (SegmentPlugin_ConditionException $e) {
                // do nothing
            }
        }

        return $joins;
    }

    private function loadSubscribers($messageId, array $conditions, $combine)
    {
        $highest = $this->dao->highestSubscriberId();
        $subscribers = BitArray::fromInteger($highest + 1);
        $joins = $this->selectionQueryJoins($conditions);

        if (count($joins) > 0) {
            foreach ($this->dao->subscribers($messageId, $joins, $combine) as $row) {
                $subscribers[(int) $row['id']] = 1;
            }
        }

        return $subscribers;
    }

    private function calculateSubscribers($messageId, array $conditions, $combine)
    {
        $this->logger->debug(sprintf(
            "Prior usage %s\nPrior peak usage %s\nPrior peak real usage %s",
            memory_get_usage(), memory_get_peak_usage(), memory_get_peak_usage(true)
        ));
        $joins = $this->selectionQueryJoins($conditions);
        $count = $this->dao->calculateSubscribers($messageId, $joins, $combine);
        $this->logger->debug(sprintf(
            "Post usage %s\nPost peak usage %s\nPost peak real usage %s",
            memory_get_usage(), memory_get_peak_usage(), memory_get_peak_usage(true)
        ));

        return $count;
    }

    private function render($template, $params)
    {
        extract($params);
        ob_start();
        require $this->coderoot . $template;

        return ob_get_clean();
    }

    /**
     * Saves the segment as a message data field.
     *
     * @param int   $messageId message id
     * @param array $segment   segment
     * @param array $toUnset   optional segment fields to be unset
     */
    private function saveMessageSegment($messageId, array $segment, array $toUnset = [])
    {
        foreach ($toUnset as $item) {
            unset($segment[$item]);
        }
        setMessageData($messageId, 'segment', $segment);
    }

    /**
     * Remove duplicate entries from a multi-dimensional array.
     *
     * @param array $input
     *
     * @return array
     */
    private function array_unique(array $input)
    {
        return array_values(
            array_intersect_key(
                $input,
                array_unique(
                    array_map('serialize', $input)
                )
            )
        );
    }

    /**
     * Constructor.
     */
    public function __construct()
    {
        $this->coderoot = dirname(__FILE__) . '/' . __CLASS__ . '/';
        $this->settings = array(
            'segment_campaign_max' => array(
              'description' => s('The maximum number of earlier campaigns to select from'),
              'type' => 'integer',
              'value' => 10,
              'allowempty' => 0,
              'min' => 4,
              'max' => 25,
              'category' => 'Segmentation',
            ),
            'segment_saved_summary' => array(
              'description' => s('Summary of saved segments'),
              'type' => 'textarea',
              'value' => '',
              'allowempty' => true,
              'category' => 'Segmentation',
            ),
        );
        $this->error_level = E_ALL ^ E_NOTICE ^ E_DEPRECATED ^ E_STRICT;

        parent::__construct();
        $this->version = (is_file($f = $this->coderoot . self::VERSION_FILE))
            ? file_get_contents($f)
            : '';
    }

    /**
     * Provide the dependencies for enabling this plugin.
     *
     * @return array
     */
    public function dependencyCheck()
    {
        global $plugins;

        return array(
            'Common plugin version 3.5.6 or greater installed' => (
                phpListPlugin::isEnabled('CommonPlugin')
                && version_compare($plugins['CommonPlugin']->version, '3.5.6') >= 0
            ),
            'PHP version 5.4.0 or greater' => version_compare(PHP_VERSION, '5.4') > 0,
        );
    }

    /**
     * Use this method as a hook to create the dao
     * Need to create autoloader because of the unpredictable order in which plugins are called.
     */
    public function sendFormats()
    {
        global $plugins;

        require_once $plugins['CommonPlugin']->coderoot . 'Autoloader.php';
        $this->dao = new SegmentPlugin_DAO(new CommonPlugin_DB());
        $this->logger = CommonPlugin_Logger::instance();

        return;
    }

    /**
     * List of items to add to menu.
     *
     * @return array
     */
    public function adminmenu()
    {
        return array();
    }

    /**
     * Build contents of additional tab.
     *
     * @param int   $messageId
     * @param array $messageData
     *
     * @return string the html for the tab
     */
    public function sendMessageTab($messageId = 0, $messageData = array())
    {
        global $pagefooter;

        $er = error_reporting($this->error_level);
        $segment = isset($messageData['segment']) ? $messageData['segment'] : array();
        $conditions = (isset($segment['c']))
            ? array_values($this->filterEmptyFields($segment['c']))
            : array();
        $saved = new SegmentPlugin_SavedSegments();

        if (isset($segment['remove'])) {
            $this->saveMessageSegment($messageId, $segment, ['c', 'combine', 'remove']);
            $conditions = [];
        } elseif (isset($segment['save']) && $segment['savename'] != '') {
            /*
             *  Save the current set of conditions
             */
            $saved->addSegment($segment['savename'], $this->filterIncompleteConditions($conditions));
            $this->saveMessageSegment($messageId, $segment, ['save']);
        } elseif (isset($segment['load']) && isset($segment['usesaved']) && is_array($segment['usesaved'])) {
            /*
             *  Load saved segments and save the message data
             */
            try {
                foreach ($segment['usesaved'] as $savedId) {
                    $savedConditions = $saved->segmentById($savedId);
                    $conditions = array_merge($conditions, $savedConditions);
                }
            } catch (Exception $e) {
                // do nothing
            }
            $conditions = $this->array_unique($conditions);
            $segment['c'] = $conditions;
            $this->saveMessageSegment($messageId, $segment, ['load', 'usesaved']);
        }
        $combine = isset($segment['combine'])
            ? $segment['combine'] : SegmentPlugin_Operator::ALL;

        $conditions[] = array('field' => '');
        $selectPrompt = s('Select ...');
        $params = array();
        $params['condition'] = array();
        $params['selectPrompt'] = $selectPrompt;
        $cf = new SegmentPlugin_ConditionFactory($this->dao);

        foreach ($conditions as $i => $c) {
            $s = new stdClass();
            $params['condition'][] = $s;

            // display field selection drop-down list
            $s->fieldList = CHtml::dropDownList(
                "segment[c][$i][field]",
                $c['field'],
                array('Subscriber Data' => $cf->subscriberFields(), 'Attributes' => $cf->attributeFields()),
                array('prompt' => $selectPrompt, 'class' => 'autosubmit')
            );

            // display hidden input to detect when field changes
            $s->hiddenField = CHtml::hiddenField("segment[c][$i][_field]", $c['field']);
            $field = $c['field'];

            if ($field == '') {
                continue;
            }

            try {
                $condition = $cf->createCondition($field);
            } catch (SegmentPlugin_ConditionException $e) {
                $s->error = sprintf('Unable to display condition: %s', $e->getMessage());
                continue;
            }
            $condition->messageData = $messageData;

            // display operators drop-down list
            $operators = $condition->operators();

            $op = ($field == $c['_field'] && isset($c['op'])) ? $c['op'] : key($operators);
            $s->operatorList = CHtml::dropDownList(
                "segment[c][$i][op]",
                $op,
                $operators,
                array('class' => 'autosubmit')
            );

            // display value field
            $value = ($field == $c['_field'] && isset($c['value'])) ? $c['value'] : '';
            $s->display = $condition->display($op, $value, "segment[c][$i]");
        }

        // display warning if no lists have been selected
        if (!(is_array($messageData['targetlist']) && count($messageData['targetlist']) > 0)) {
            $params['warning'] = s('Please select at least one list on the Lists tab before adding segmentation conditions');
        }

        // display fields for saved segments only where there are some
        $savedListData = $saved->selectListData();

        if (count($savedListData) > 0) {
            $params['savedList'] = CHtml::dropDownList(
                'segment[usesaved][]',
                '',
                $savedListData,
                array('multiple' => 'multiple', 'style' => 'width: 50%')
            );
            $params['loadButton'] = CHtml::submitButton(s('Load segments'), array('name' => 'segment[load]'));
            $params['settingsButton'] = new CommonPlugin_PageLink(
                new CommonPlugin_PageURL('configure', array(), 'segmentation'),
                'Edit saved segments',
                array('target' => '_blank', 'class' => 'button')
            );
        }

        // display calculate button
        $params['calculateButton'] = CHtml::submitButton(s('Calculate'), array('name' => 'segment[calculate]'));

        // display combine drop-down list
        $params['combineList'] = CHtml::dropDownList(
            'segment[combine]',
            $combine,
            array(SegmentPlugin_Operator::ONE => s('any'), SegmentPlugin_Operator::ALL => s('all'))
        );

        // display calculated number of subscribers
        if (isset($segment['calculate'])) {
            try {
                $params['totalSubscribers'] = $this->calculateSubscribers(
                    $messageId,
                    $this->filterIncompleteConditions($segment['c']),
                    $combine
                );
            } catch (SegmentPlugin_ValueException $e) {
                $params['warning'] = s('One of the conditions has an invalid target value');
            }
        }

        // display remove all, save button and input field only when there is at least one entered condition
        if (count($conditions) > 1) {
            $params['removeButton'] = CHtml::submitButton(s('Remove all'), array('name' => 'segment[remove]'));
            $params['saveButton'] = CHtml::submitButton(s('Save segment'), array('name' => 'segment[save]'));
            $params['saveName'] = CHtml::textField('segment[savename]', '', array('size' => 25, 'placeholder' => 'Name of segment'));
        }

        // display link to Help page
        $params['help'] = CHtml::tag(
            'a',
            array('href' => self::GUIDANCE, 'target' => '_blank'),
            new \phpList\plugin\Common\ImageTag('info.png', 'Guidance')
        );
        $html = $this->render('sendtab.tpl.php', $params);
        $pagefooter[basename(__FILE__)] = file_get_contents($this->coderoot . 'script.html');
        error_reporting($er);

        return $html;
    }

    /**
     * The title of the additional tab.
     *
     * @param int $messageId
     *
     * @return string the title
     */
    public function sendMessageTabTitle($messageid = 0)
    {
        return s('Segment');
    }

    /**
     * Use this hook to delete the 'not sent' rows from the usermessage table
     * so that they will be re-evaluated.
     *
     * @param int $id the message id
     *
     * @return none
     */
    public function messageQueued($id)
    {
        $this->deleteNotSent($id);
    }

    /**
     * The same processing as when queueing a message.
     *
     * @param int $id the message id
     *
     * @return none
     */
    public function messageReQueued($id)
    {
        $this->messageQueued($id);
    }

    /**
     * Use this hook to select the subscribers who meet the segment conditions.
     * $selectedSubscribers will contain the selected subscribers.
     *
     * @param array $messageData the message data
     *
     * @return none
     */
    public function campaignStarted($messageData = array())
    {
        $er = error_reporting($this->error_level);

        if (isset($messageData['segment']['c'])) {
            $conditions = $this->filterIncompleteConditions($messageData['segment']['c']);

            if (count($conditions) > 0) {
                try {
                    $this->selectedSubscribers = $this->loadSubscribers(
                        $messageData['id'],
                        $conditions,
                        $messageData['segment']['combine']
                    );
                } catch (SegmentPlugin_ValueException $e) {
                    logEvent("Invalid segment condition, message {$messageData['id']}");
                }
            }
        }
        error_reporting($er);
    }

    /**
     * Determine whether the campaign should be sent to a specific user.
     *
     * @param array $messageData the message data
     * @param array $userData    the user data
     *
     * @return bool
     */
    public function canSend($messageData, $userData)
    {
        return ($this->selectedSubscribers === null)
            ? true
            : (bool) $this->selectedSubscribers[(int) $userData['id']];
    }

    /**
     * Build the html to be added to the view message page.
     *
     * @param int   $messageId   the message id
     * @param array $messageData the message data
     *
     * @return array|false the caption and html to be added, or false if the message
     *                     does not use segments
     */
    public function viewMessage($messageId, array $messageData)
    {
        $er = error_reporting($this->error_level);

        if (!isset($messageData['segment'])) {
            return false;
        }
        $segment = $messageData['segment'];

        if (!isset($segment['c'])) {
            return false;
        }
        $conditions = array_values($this->filterEmptyFields($segment['c']));

        if (count($conditions) == 0) {
            return false;
        }
        $combine = isset($segment['combine'])
            ? $segment['combine'] : SegmentPlugin_Operator::ALL;

        $params = array();
        $params['condition'] = array();
        $cf = new SegmentPlugin_ConditionFactory($this->dao);

        foreach ($conditions as $i => $c) {
            $s = new stdClass();
            $params['condition'][] = $s;
            $field = $c['field'];

            try {
                $condition = $cf->createCondition($field);
            } catch (SegmentPlugin_ConditionException $e) {
                $s->error = sprintf('Unable to display condition: %s', $e->getMessage());
                continue;
            }
            $condition->messageData = $messageData;

            // display field selection
            $fields = $cf->subscriberFields() + $cf->attributeFields();
            $s->field = $fields[$field];

            // display operator
            $operators = $condition->operators();
            $op = ($field == $c['_field'] && isset($c['op'])) ? $c['op'] : key($operators);
            $s->operator = $operators[$op];

            // display value field
            $value = ($field == $c['_field'] && isset($c['value'])) ? $c['value'] : '';
            $s->display = $condition->display($op, $value, "segment[c][$i]");
        }

        // display combine
        $combineOps = array(SegmentPlugin_Operator::ONE => s('any'), SegmentPlugin_Operator::ALL => s('all'));
        $params['combine'] = $combineOps[$combine];

        $html = $this->render('viewmessage.tpl.php', $params);
        error_reporting($er);

        return array('Segment conditions', $html);
    }

    /**
     * Called when a campaign is being copied.
     * Allows this plugin to specify which rows of the messagedata table should also
     * be copied.
     *
     * @return array rows of messagedata table that should be copied
     */
    public function copyCampaignHook()
    {
        return array('segment');
    }
}

Filemanager

Name Type Size Permission Actions
CKEditorPlugin Folder 0755
CaptchaPlugin Folder 0755
Common Folder 0755
CommonPlugin Folder 0755
SegmentPlugin Folder 0755
defaultplugin Folder 0755
fckphplist Folder 0755
sidebar Folder 0755
.htaccess File 145 B 0644
CKEditorPlugin.php File 10.37 KB 0644
COPYING.txt File 34.32 KB 0644
CaptchaPlugin.php File 7.96 KB 0644
CommonPlugin.php File 3.78 KB 0644
SegmentPlugin.php File 18.37 KB 0644
fckphplist.php File 2.44 KB 0644
helloworld.php File 265 B 0644
inviteplugin.php File 3.89 KB 0644
sidebar.php File 241 B 0644
subjectLinePlaceholdersPlugin.php File 5.27 KB 0644
update.sh File 66 B 0644