Add missing file StoreComponent.php, a=chris

Chris Pollett [2018-05-14 03:May:th]
Add missing file StoreComponent.php, a=chris
Filename
src/controllers/components/StoreComponent.php
diff --git a/src/controllers/components/StoreComponent.php b/src/controllers/components/StoreComponent.php
new file mode 100644
index 000000000..54f47d743
--- /dev/null
+++ b/src/controllers/components/StoreComponent.php
@@ -0,0 +1,484 @@
+<?php
+/**
+ * SeekQuarry/Yioop --
+ * Open Source Pure PHP Search Engine, Crawler, and Indexer
+ *
+ * Copyright (C) 2009 - 2018  Chris Pollett chris@pollett.org
+ *
+ * LICENSE:
+ *
+ * This program 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.
+ *
+ * This program 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ *
+ * END LICENSE
+ *
+ * @author Pushkar Umaranikar
+ * @license https://www.gnu.org/licenses/ GPL3
+ * @link https://www.seekquarry.com/
+ * @copyright 2009 - 2018
+ * @filesource
+ */
+namespace seekquarry\yioop\controllers\components;
+
+use seekquarry\yioop\configs as C;
+use seekquarry\yioop\library as L;
+use seekquarry\yioop\library\UrlParser;
+
+/**
+ * Component of the Yioop control panel used to handle activitys for
+ * managing advertisements. i.e., create advertisement, activate/
+ * deactivate advertisement, edit advertisement.It is used by AdminController
+ *
+ * @author Pushkar Umaranikar (enhancements Chris Pollett)
+ */
+class StoreComponent extends Component
+{
+    /**
+     * Used to manage the purchase and storage of advertising credits
+     *
+     * @return array $data field variables necessary for display of view
+     */
+    public function manageCredits()
+    {
+        $parent = $this->parent;
+        $credit_model = $parent->model("credit");
+        $signin_model = $parent->model("signin");
+        $user_model = $parent->model("user");
+        $data = [];
+        $data['SCRIPT'] = "";
+        $data['MESSAGE'] = "";
+        $data["ELEMENT"] = "managecredits";
+        $data["AMOUNTS"] = [0 => tl('store_component_credit_amounts'),
+            "10" => tl('store_component_ten_in_credits'),
+            "20" => tl('store_component_twenty_in_credits'),
+            "50" => tl('store_component_fifty_in_credits'),
+            "100" => tl('store_component_hundred_in_credits'),
+        ];
+        $data['COST_AMOUNTS'] = [
+            10 => 1000, 20 => 2000, 50 => 5000, 100 => 10000,
+        ];
+        $data['MONTHS'] = [ 0 => tl('store_component_month'),
+            "01" => "01", "02" => "02", "03" => "03",
+            "04" => "04", "05" => "05", "06" => "06", "07" => "07",
+            "08" => "08", "09" => "09", "10" => "10", "11" => "11",
+            "12" => "12"
+        ];
+        $user_id = $_SESSION['USER_ID'];
+        $username = $signin_model->getUserName($user_id);
+        $data["USER"] = $user_model->getUser($username);
+        $data["USER_ID"] = $user_id;
+        $current_year = date('Y');
+        $data['YEARS'] = [ 0 => tl('store_component_year')];
+        for ( $year = $current_year; $year < $current_year + 20; $year++ ) {
+            $data['YEARS'][$year] = $year;
+        }
+        $arg = (isset($_REQUEST['arg'])) ? $parent->clean($_REQUEST['arg'],
+            "string") : "";
+        $num_dollars = (isset($_REQUEST['NUM_DOLLARS']) &&
+            isset($data['COST_AMOUNTS'][$_REQUEST['NUM_DOLLARS']])) ?
+            $_REQUEST['NUM_DOLLARS'] : 0;
+        $data['BALANCE'] = $credit_model->getCreditBalance($user_id);
+        if (C\CreditConfig::isActive() && (!($user_id == C\ROOT_ID &&
+            C\ALLOW_FREE_ROOT_CREDIT_PURCHASE))) {
+            $data["INCLUDE_SCRIPTS"][] = 'credit';
+            $ad_script_found = false;
+            for ($i = C\YIOOP_VERSION; $i >= C\MIN_AD_VERSION; $i--) {
+                $get_credit_token_initialize_script =
+                    "FN" . md5(UrlParser::getBaseDomain(C\NAME_SERVER) .
+                    $i . "getCreditTokenInitializeScript");
+                if (method_exists( C\NS_CONFIGS . "CreditConfig",
+                    $get_credit_token_initialize_script)) {
+                    $ad_script_found = true;
+                    break;
+                }
+            }
+            if ($ad_script_found) {
+                $data['SCRIPT'] .=
+                    C\CreditConfig::$get_credit_token_initialize_script();
+            } else {
+                $data['DISPLAY_MESSAGE'] =
+                    tl('store_component_script_failure');
+            }
+        }
+        switch ($arg)
+        {
+            case "purchaseCredits":
+                $message = "";
+                if ($num_dollars <= 0) {
+                    return $parent->redirectWithMessage(
+                        tl('store_component_invalid_credit_quantity'),
+                        []);
+                }
+                /*  string to translate stored in column of 32 chars
+                    so not writing advertisement_component
+                 */
+                $strings_to_translate_for_model = [
+                    tl('advertisement_buy_credits'),
+                    tl('advertisement_init_ledger')];
+                $token = $parent->clean($_REQUEST['CREDIT_TOKEN'], "string");
+                if (!($user_id == C\ROOT_ID &&
+                    C\ALLOW_FREE_ROOT_CREDIT_PURCHASE)) {
+                    $is_active = C\CreditConfig::isActive();
+                    if ($is_active && empty($token)) {
+                        return $parent->redirectWithMessage(
+                            tl('store_component_credit_token_empty'),
+                            []);
+                    }
+                    if ($is_active && !C\CreditConfig::charge(
+                        $num_dollars, $parent->clean(
+                        $_REQUEST['CREDIT_TOKEN'], "string"), $message)) {
+                        return $parent->redirectWithMessage(
+                            tl('store_component_processing_error',
+                                $message), []);
+                    }
+                }
+                $credit_model->updateCredits($user_id,
+                    $data['COST_AMOUNTS'][$num_dollars],
+                    'advertisement_buy_credits');
+                return $parent->redirectWithMessage(
+                    tl('store_component_credits_purchased'),
+                    []);
+                break;
+        }
+        $search_array = [["timestamp", "", "", "DESC"]];
+        $parent->pagingLogic($data, $credit_model, "TRANSACTIONS",
+            C\DEFAULT_ADMIN_PAGING_NUM, $search_array, "",
+            ["USER_ID" => $user_id]);
+        return $data;
+    }
+    /**
+     * Used to handle the Create, Edit and Activation of Advertisements
+     *
+     * @return array $data field variables necessary for display of view
+     */
+    public function manageAdvertisements()
+    {
+        $parent = $this->parent;
+        $signin_model = $parent->model("signin");
+        $user_model = $parent->model("user");
+        $role_model = $parent->model('role');
+        $advertisement_model = $parent->model("advertisement");
+        $credit_model = $parent->model("credit");
+        $data = [];
+        $data['DURATIONS'] = [ 0 => tl('store_component_num_days'),
+            1 => tl('store_component_one_day'),
+            7 => tl('store_component_seven_days'),
+            30 => tl('store_component_thirty_days'),
+            90 => tl('store_component_ninety_days'),
+            180 => tl('store_component_one_eighty_days'),
+        ];
+        $request_field_types = [
+            'context' => 'string',
+            "start_row" => 'int', "num_show"  => 'int', "end_row"  => 'int',
+            "NAME" => 'string', "DESTINATION" => 'web-url',
+            "DESCRIPTION"  => 'string', "KEYWORDS"  => 'string',
+            "BUDGET"  => 'int', "DURATION" => array_keys($data['DURATIONS']),
+            'id' => 'int', 'status' => 'int'];
+        $request_fields = array_keys($request_field_types);
+        $data['MONTHS'] = [ 0 => tl('store_component_month'),
+            "01" => "01", "02" => "02", "03" => "03",
+            "04" => "04", "05" => "05", "06" => "06", "07" => "07",
+            "08" => "08", "09" => "09", "10" => "10", "11" => "11",
+            "12" => "12"
+        ];
+        $current_year = date('Y');
+        $data['YEARS'] = [ 0 => tl('store_component_year')];
+        for ( $year = $current_year; $year < $current_year + 20; $year++ ) {
+            $data['YEARS'][$year] = $year;
+        }
+        $data['SCRIPT'] = "";
+        $data['MESSAGE'] = "";
+        $data["ELEMENT"] = "manageadvertisements";
+        $data['FORM_TYPE'] = "addadvertisement";
+        $data['DURATION'] = 0;
+        foreach ($request_field_types as $field => $type) {
+            if (isset($_REQUEST[$field])) {
+                $data[$field] = $parent->clean($_REQUEST[$field], $type);
+            }
+        }
+        if (isset($_REQUEST['EDIT_AD'])) {
+            unset($_REQUEST['CALCULATE']);
+            unset($_REQUEST['arg']);
+        }
+        if (isset($_REQUEST['CALCULATE']) || (isset($_REQUEST['arg']) &&
+            $_REQUEST['arg'] == "addadvertisement")) {
+            if (empty($_REQUEST['NAME']) ||
+                empty($_REQUEST['DESCRIPTION']) ||
+                empty($_REQUEST['DESTINATION'])) {
+                return $parent->redirectWithMessage(
+                    tl('store_component_fields_cannot_be_empty'),
+                    array_merge([$_REQUEST['arg']], $request_fields));
+            }
+            if (!isset($_REQUEST['DURATION']) || $_REQUEST['DURATION'] == 0) {
+                return $parent->redirectWithMessage(
+                    tl('store_component_duration_cannot_be_empty'),
+                    array_merge([$_REQUEST['arg']], $request_fields));
+            }
+            if (empty($_REQUEST['KEYWORDS'])) {
+                return $parent->redirectWithMessage(
+                    tl('store_component_enter_keywords'),
+                    array_merge([$_REQUEST['arg']], $request_fields));
+            }
+            $data['START_DATE'] = date(C\AD_DATE_FORMAT);
+            $_REQUEST['START_DATE'] = $data['START_DATE'];
+            $start_date = strtotime($data['START_DATE']);
+            $data['END_DATE'] = date(C\AD_DATE_FORMAT,
+                $start_date + (($data['DURATION'] - 1) * C\ONE_DAY));
+            $_REQUEST['END_DATE'] = $data['END_DATE'];
+            $this->initializeAdKeywords($data, $start_date, $data['DURATION']);
+        }
+        $user_id = $_SESSION['USER_ID'];
+        $is_admin = $role_model->checkUserRole($user_id, C\ADMIN_ROLE);
+        $data['HAS_ADMIN_ROLE'] = $is_admin;
+        $username = $signin_model->getUserName($user_id);
+        $data["USER"] = $user_model->getUser($username);
+        $data["USER_ID"] = $user_id;
+        $data['PAGING'] = "";
+        $search_array = [];
+        $arg = (isset($_REQUEST['arg'])) ? $parent->clean($_REQUEST['arg'],
+            "string") : "";
+        $data['BALANCE'] = $credit_model->getCreditBalance($user_id);
+        switch ($arg)
+        {
+            case "addadvertisement":
+                if ( isset($_REQUEST['PURCHASE'])) {
+                    $advertisement = [];
+                    $advertisement['USER_ID'] = $user_id;
+                    $fields = ["NAME", "DESCRIPTION",
+                        "DESTINATION", "BUDGET", "KEYWORDS",
+                        "START_DATE", "END_DATE"];
+                    foreach ($fields as $field) {
+                        if (isset($_REQUEST[$field])) {
+                            $advertisement[$field] = $data[$field];
+                        }
+                    }
+                    if (empty($_REQUEST['KEYWORDS'])) {
+                        return $parent->redirectWithMessage(
+                            tl('store_component_enter_keywords'),
+                            array_merge(['arg'], $request_fields));
+                    }
+                    $ad_start_date = $data['START_DATE'];
+                    if ($advertisement["BUDGET"] < $data['AD_MIN_BID']) {
+                        return $parent->redirectWithMessage(
+                            tl('store_component_bid_too_low'),
+                            array_merge(['arg'], $request_fields));
+                    }
+                    if ($data['BALANCE'] < $advertisement["BUDGET"]) {
+                        return $parent->redirectWithMessage(
+                            tl('store_component_too_few_credits'),
+                            array_merge(['arg'], $request_fields));
+                    }
+                    $message = "";
+                    $strings_to_translate_for_model =
+                        [tl('advertisement_buy_ad')];
+                    $advertisement_model->addAdvertisement($advertisement,
+                        $data["AD_KEYWORDS"], $data['AD_MIN_BID'], $user_id);
+                    $credit_model->updateCredits($user_id,
+                        -$data["BUDGET"],
+                        'advertisement_buy_ad');
+                    $preserve = [];
+                    if (!empty($_REQUEST['context'])) {
+                        $_REQUEST['arg'] = 'search';
+                        $preserve[] = 'arg';
+                    }
+                    return $parent->redirectWithMessage(
+                        tl('store_component_ad_created'),
+                        array_merge($preserve,
+                        ["start_row", "num_show", "end_row"]));
+                }
+                break;
+            case "changestatus":
+                if (isset($_REQUEST['id'])) {
+                    $ad = $advertisement_model->getAdvertisementById(
+                        $data['id']);
+                    if (empty($ad) || ($user_id != $ad['USER_ID'] &&
+                        !$is_admin) ) {
+                        break;
+                    }
+                    $user_ad_statuses = [C\ADVERTISEMENT_ACTIVE_STATUS,
+                        C\ADVERTISEMENT_DEACTIVATED_STATUS];
+                    $admin_ad_statuses = [C\ADVERTISEMENT_ACTIVE_STATUS,
+                        C\ADVERTISEMENT_SUSPENDED_STATUS];
+                    if ($user_id == $ad['USER_ID'] && !in_array(
+                        $data['status'], $user_ad_statuses)) {
+                        break;
+                    } else if ($user_id != $ad['USER_ID'] &&
+                        $is_admin && !in_array(
+                        $data['status'], $admin_ad_statuses)) {
+                        break;
+                    }
+                    $result = $advertisement_model->setAdvertisementStatus(
+                        $data['id'], $data['status']);
+                    if ($result) {
+                    $preserve = ["start_row", "end_row", "num_show"];
+                        if (!empty($_REQUEST['context'])) {
+                            $_REQUEST['arg'] = 'search';
+                            $preserve[] = 'arg';
+                        }
+                        return $parent->redirectWithMessage(tl(
+                            tl('store_component_status_changed')),
+                            array_merge($preserve, $request_fields));
+                    }
+                }
+                break;
+            case "editadvertisement":
+                $data["FORM_TYPE"] = "editadvertisement";
+                $update = false;
+                if (isset($_REQUEST['save'])) {
+                    $update = true;
+                }
+                if (isset($_REQUEST['id'])) {
+                    $ad = $advertisement_model->getAdvertisementById(
+                        $data['id']);
+                    $ad_fields = ["NAME", "DESTINATION",
+                        "DESCRIPTION","BUDGET","KEYWORDS",
+                        "START_DATE", 'END_DATE'];
+                    if (!empty($ad) && ($user_id == $ad['USER_ID'] ||
+                        $is_admin)) {
+                        foreach ($ad_fields as $field) {
+                            $data[$field] = isset($data[$field])  ?
+                                $data[$field] : $ad[$field];
+                        }
+                        if ($is_admin) {
+                            $data['AD_USER_NAME'] = $user_model->getUsername(
+                                $ad['USER_ID']);
+                        }
+                        if ($update) {
+                            $updated_advertisement = [];
+                            $ad_update_fields = ["NAME",
+                                "DESCRIPTION","DESTINATION"];
+                            foreach ($ad_update_fields as $field) {
+                                if (isset($_REQUEST[$field])) {
+                                    $updated_advertisement[$field] =
+                                        $data[$field];
+                                }
+                            }
+                            $advertisement_model->updateAdvertisement(
+                                $updated_advertisement, $data['id']);
+                            foreach ($request_fields as $field) {
+                                unset($data[$field]);
+                            }
+                            unset($data['START_DATE']);
+                            unset($data['END_DATE']);
+                            return $parent->redirectWithMessage(
+                                tl('store_component_ad_updated'),
+                                ["arg", "id", "start_row", "num_show",
+                                "end_row", "context"]);
+                        }
+                    }
+                }
+                break;
+            case "search":
+                $data["FORM_TYPE"] = "search";
+                $search_array =
+                    $parent->tableSearchRequestHandler($data,
+                        "manageAdvertisements",
+                        ['name', 'description', 'destination', 'keywords',
+                        'budget', 'start_date', 'end_date']);
+                if (empty($_SESSION['LAST_SEARCH']['manageAdvertisements']) ||
+                    isset($_REQUEST['name'])) {
+                    $_SESSION['LAST_SEARCH']['manageAdvertisements'] =
+                        $_SESSION['SEARCH']['manageAdvertisements'];
+                    unset($_SESSION['SEARCH']['manageAdvertisements']);
+                } else {
+                    $default_search = true;
+                }
+                break;
+        }
+        if ($search_array == [] || !empty($default_search)) {
+            if (!empty($_SESSION['LAST_SEARCH']['manageAdvertisements'])) {
+                if (!empty($_REQUEST['arg']) && $_REQUEST['arg'] == 'search') {
+                    $search_array =
+                        $parent->restoreLastSearchFromSession($data,
+                        'manageAdvertisements');
+                } else if (!empty($_REQUEST['context'])) {
+                    $search_array =
+                        $_SESSION['LAST_SEARCH']['manageAdvertisements'][
+                        'SEARCH_ARRAY'];
+                    $data['PAGING'] = $_SESSION['LAST_SEARCH'][
+                        'manageAdvertisements']['PAGING'];
+                }
+            }
+            if ($search_array == []) {
+                $search_array[] = ["id", "", "", "DESC"];
+            }
+        }
+        if (!$_SERVER["MOBILE"]) {
+            $data['SCRIPT'] .= "\npreview(elt('ad-name'))\n" .
+                "preview(elt('ad-description'))\n".
+                "preview(elt('ad-destination'), 'ad-name')\n";
+        }
+        $parent->pagingLogic($data, $advertisement_model, "ADVERTISEMENTS",
+            C\DEFAULT_ADMIN_PAGING_NUM, $search_array, "",
+            ["USER_ID" => $user_id, "ADMIN" => $is_admin]);
+        return $data;
+    }
+    /**
+     * Sets up the $data['AD_KEYWORD'] as an associative array of
+     * (keyword, day) => bid_amounts based on min bid for that ad keyword on
+     * that day. Set up $data['EXPENSIVE_KEYWORD'] as the most expensive
+     * ad keyword for the dates in question and also sets up $data['AD_MIN_BID']
+     * as the minimum bid required for the dates in question
+     *
+     * @param array &$data associative array of data used by the view to
+     *      draw itself
+     * @param int $start_date state date in seconds since beginning of Unix
+     *  epoch
+     * @param int $day_count number of days ad campaign will last
+     */
+    public function initializeAdKeywords(&$data, $start_date, $day_count)
+    {
+        $parent = $this->parent;
+        $keywords = explode("," , strtoupper($data['KEYWORDS']));
+        array_walk($keywords, [C\NS_COMPONENTS .
+            "AdvertisementComponent", "trim_value"]);
+        $min_bid_reqd = 0;
+        $expensive_bid = 0;
+        foreach ($keywords as $keyword) {
+            $date = date(C\AD_DATE_FORMAT, $start_date);
+            $keyword_bid_amount = 0;
+            for ($k = 0; $k < $day_count; $k++) {
+                $bid_amount = $parent->model('advertisement')->getBidAmount(
+                    $keyword, $date);
+                $half_bid = ceil($bid_amount/2);
+                if ($bid_amount > C\AD_KEYWORD_INIT_BID ) {
+                    $min_bid_reqd += $half_bid;
+                    $data['AD_KEYWORDS'][$keyword][$date] =
+                        $half_bid;
+                    $keyword_bid_amount += $half_bid;
+                } else {
+                    $min_bid_reqd += $bid_amount;
+                    $data['AD_KEYWORDS'][$keyword][$date] =
+                        $half_bid;
+                    $keyword_bid_amount += $half_bid;
+                }
+                $date = date(C\AD_DATE_FORMAT, strtotime($date .' +1 day'));
+            }
+            if ($keyword_bid_amount >= $expensive_bid) {
+                $expensive_bid = $keyword_bid_amount;
+                $data['EXPENSIVE_KEYWORD'] = $keyword;
+            }
+        }
+        $data['AD_MIN_BID'] = $min_bid_reqd;
+    }
+    /**
+     * Trim white spaces callback for array_walk
+     *
+     * @param string& $value string to remove initial and trailing whitespace
+     *      from
+     */
+    public function trim_value(&$value)
+    {
+        $value = trim($value);
+    }
+}
ViewGit