<?php
/* Logaholic Web Analytics software             Copyright(c) 2005-2013 Logaholic B.V.
 *                                                               All rights Reserved.
 * This code is subject to the Logaholic license. Unauthorized copying is prohibited.
 * support@logaholic.com                         http://www.logaholic.com/License.txt
*/

/**
 * @desc This contains common functions for the API
 */

function SetEmailAlerts()
{
    global $config, $db;

    if (!isset($_GET['using'])) {
        Output("Missing 'using' parameter.", true);
    }
    if ($_GET['using'] != 1 && $_GET['using'] != 0) {
        Output("Parameter must be 1 or 0.", true);
    }

    $running_from_command_line = true;
    include_once $config['path'] . "/common.inc.php";

    setGlobalSetting("ToggleEmailAlerts", $_GET['using']);
}

function SetReportStore()
{
    global $config, $db;
    if (!isset($_GET['using'])) {
        Output("Missing 'using' parameter.", true);
    }
    if ($_GET['using'] !== 'true' && $_GET['using'] !== 'false') {
        Output("Parameter must be 'true' or 'false'.", true);
    }

    $running_from_command_line = true;
    include_once $config['path'] . "/common.inc.php";

    # cant set a boolean from the url.. So set it now.
    if ($_GET['using'] === 'false') {
        $_GET['using'] = 0;
    }
    if ($_GET['using'] === 'true') {
        $_GET['using'] = 1;
    }

    setGlobalSetting("logaholic_report_store", $_GET['using']);

    if ($_GET['using']) {
        Output("Enabled the report store.");
    } else {
        Output("Disabled the report store.");
    }
}

function ReadVars()
{
    global $action, $argv, $argc;
    $stdin_stream = fopen('php://stdin', 'r');
    if (strpos(@$argv[1], "=") !== false) {
        // If we've passed in a command line, push it into the $_GET section
        // this means we can support name=value pairs as command line options
        if ($argc > 0) {
            for ($i = 1; $i < $argc; $i++) {
                parse_str($argv[$i], $tmp);
                $_GET = array_merge($_GET, array_map('urldecode', $tmp));
            }
        }
    } elseif (is_resource($stdin_stream)) {
        if ($line = fgets($stdin_stream, 1024)) {
            parse_str(trim($line), $tmp);
            $_GET = array_merge($_GET, array_map('urldecode', $tmp));
        }
    }
    if (isset($_GET['action'])) {
        $action = $_GET['action'];
    }
}

function AccessControl($password_for_this_script)
{
    if (!empty($_SERVER['DOCUMENT_ROOT']) && empty($password_for_this_script)) {
        Output("This script should be started from the command line only.<br>Terminating.\n", true);
    }

    if ($password_for_this_script == "") {
        Output("Edit config.php and provide a password first!", true);
    }
    if (!isset($_GET['api_password'])) {
        Output("Please include api_password=[password] in the URI of any api based requests\n", true);
    } else {
        if ($_GET['api_password'] != $password_for_this_script) {
            Output("Access Denied", true);
        }
    }
    return;
}

function getProfileList($username)
{
    global $db;


    $query = $db->Execute(
        "select profiles from " . TBL_USERS . " where username=" . $db->Quote($username)
    ) or Output("An error occurred:" . $db->ErrorMsg(), true);;


    if ($query->NumRows() == 0) {
        Output("An error occurred: User $username not found", true);
        return false;
    }
    $q = $query->FetchRow();
    return $q['profiles'];
}

function saveProfileList($username, $profile_list)
{
    global $db;

    $db->Execute(
        "UPDATE " . TBL_USERS . " SET profiles=" . $db->Quote($profile_list) . " WHERE username=" . $db->Quote(
            $username
        )
    ) or Output("An error occurred: " . $db->ErrorMsg(), true);
}

/**
 * @desc This function returns the users that have access to a given profile
 */
function GetUsersForProfile($profilename)
{
    global $db;
    $users = array();
    $q = $db->Execute(
        "select username from " . TBL_USERS . " where (profiles=" . $db->Quote(
            $profilename
        ) . " or profiles like " . $db->Quote("$profilename,%") . " or profiles like " . $db->Quote(
            "%,$profilename,%"
        ) . " or profiles like " . $db->Quote("%,$profilename") . ")"
    );
    while ($data = $q->FetchRow()) {
        if ($data['username']) {
            $users[] = $data['username'];
        }
    }
    return implode(",", $users);
}

/**
 * @desc This function deletes the profile from all users
 */
function DeleteProfileFromUsers($profilename)
{
    $users = explode(",", GetUsersForProfile($profilename));

    foreach ($users as $user) {
        if (empty($user)) { # This was a profile with no user
            continue;
        }

        $plist = getProfileList($user);
        $plist_arr = explode(',', $plist);
        $plist_arr_keep = array();
        foreach ($plist_arr as $site) {
            $site = trim($site);
            if ($site && $site != $profilename) {
                $plist_arr_keep[] = $site;
            }
        }
        $plist = (count($plist_arr_keep)) ? implode(',', $plist_arr_keep) : '';
        saveProfileList($user, $plist);
    }
}

function affiliateID()
{
    if (!isset($_GET['affiliateid'])) {
        Output("Need parameter: affiliateid", true);
        return false;
    }
    if (setGlobalSetting("affiliate_id", $_GET['affiliateid'])) {
        Output("Error", true);
        return false;
    } else {
        Output("Success: Set affiliateid to " . $_GET['affiliateid']);
        return true;
    }
}

function Output($val, $error = false, $stop_script = true)
{
    global $config, $apilog;

    if (isset($config['log_api_calls']) && $config['log_api_calls'] === true) {
        if ($error === false) {
            $apilog["Status"] = "Success";
        } else {
            $apilog["Status"] = "Error";
        }

        $v = json_encode($val);
        if (strlen($v) > 100) {
            $v = substr($v, 0, 100) . "...";
        }

        $apilog["Result"] = $v;
        WriteApiLog();
    }

    if (!isset($config['json_output']) || $config['json_output'] === false) {
        if (!is_array($val)) {
            echo $val;
        } else {
            foreach ($val as $v) {
                if (!is_array($v)) {
                    echo $v;
                }
            }
        }

        if ($stop_script === true) {
            exit();
        } else {
            return;
        }
    }

    $key = "Succes";
    if ($error) {
        $key = "Error";
    }

    if (!is_array($val)) {
        $val = array($val);
    }
    $data = array($key => $val);


    echo json_encode($data);
    if ($stop_script === true) {
        exit();
    } else {
        return;
    }
}

function WriteApiLog()
{
    global $config, $apilog, $script_start;

    if (!isset($config['log_api_calls'])) {
        return false;
    }

    if ($config['log_api_calls'] === true) {
        if (is_file('call_log')) {
            $fp = fopen("call_log", "a+");
        } else {
            return false;
        }

        $apilog['Duration'] = time() - $script_start;

        fwrite($fp, json_encode($apilog) . " \n");
        fclose($fp);
    }
}

# this will log all api calls. We only need to do this if we're debugging
function SetupApiLog($action, $request)
{
    global $config, $apilog;

    # password safety first!
    unset($request["api_password"]);

    # 4 Cpanel ....
    if (isset($request["/var/cpanel/logaholic/logaholic_api/index_php"])) {
        unset($request["/var/cpanel/logaholic/logaholic_api/index_php"]);
    }

    $parameters = array();
    foreach ($request as $k => $v) {
        if (strlen($v) > 100) {
            $v = substr($v, 0, 100) . "...";
        }
        $parameters[$k] = $v;
    }

    $apilog['Action'] = $action;
    $apilog['Parameters'] = $parameters;
}


# this adds json support to PHP versions that don't have it
if (!function_exists('json_encode')) {
    include_once($config['path'] . "/components/json/JSON.php");

    $GLOBALS['JSON_OBJECT'] = new Services_JSON();
    function json_encode($value)
    {
        return $GLOBALS['JSON_OBJECT']->encode($value);
    }

    function json_decode($value, $assoc = false)
    {
        if ($assoc == true) {
            return stdToAssoc($GLOBALS['JSON_OBJECT']->decode($value));
        } else {
            return $GLOBALS['JSON_OBJECT']->decode($value);
        }
    }
}

if (!function_exists('stdToAssoc')) {
    function stdToAssoc($obj)
    {
        $array = array();

        if (empty($obj)) {
            return null;
        }
        foreach ($obj as $key => $value) {
            if (is_object($value) == true || is_array($value) == true) {
                $array[$key] = stdToAssoc($value);
            } else {
                $array[$key] = $value;
            }
        }

        return $array;
    }
}


function folderToZip($folder, &$zipFile, $subfolder = null)
{
    if ($zipFile == null) {
        // no resource given, exit
        return false;
    }

    // we check if $folder has a slash at its end, if not, we append one
    $array = str_split($folder);
    $folder .= end($array) == "/" ? "" : "/";
    $array1 = str_split($subfolder);
    $subfolder .= end($array1) == "/" ? "" : "/";
    // we start by going through all files in $folder
    $handle = opendir($folder);
    while ($f = readdir($handle)) {
        if ($f != "." && $f != "..") {
            if (is_file($folder . $f)) {
                // if we find a file, store it
                // if we have a subfolder, store it there
                if ($subfolder != null) {
                    $zipFile->addFile($folder . $f, $subfolder . $f);
                } else {
                    $zipFile->addFile($folder . $f);
                }
            } elseif (is_dir($folder . $f)) {
                // if we find a folder, create a folder in the zip
                $zipFile->addEmptyDir($subfolder . $f);

                // and call the function again
                folderToZip($folder . $f, $zipFile, $subfolder . $f);
            }
        }
    }
}
