woocommerce/classes/integrations/shareyourcart/sdk/class.shareyourcart-base.php

1283 lines
34 KiB
PHP
Executable File

<?php
/**
* CLASS: Share Your Cart Base
* AUTHOR: Barandi Solutions
* COUNTRY: Romania
* EMAIL: catalin.paun@barandisolutions.ro
* VERSION : 1.0
* DESCRIPTION: This class is used as a base class for every PHP plugin we create.
* * Copyright (C) 2012 Barandi Solutions
*/
require_once(dirname(__FILE__) ."/class.shareyourcart-api.php");
if(!class_exists('ShareYourCartBase',false)){
abstract class ShareYourCartBase extends ShareYourCartAPI {
//this array is used to hold function calls between different instances of this class
private static $_SINGLE_FUNCTIONS_CALLS = array();
private static $_SDK_VERSION = '1.10'; //the first one is the SDK main version, while the second one is it's revision
protected static $_DB_VERSION = '1.1';
protected $SDK_ANALYTICS = true;
/**
* Constructor
* @param null
*/
function __construct() {
//set exception handler
if(set_exception_handler(array(&$this,'UncaughtExceptionHandler')) !== null)
restore_exception_handler(); //if there already was an exception handler, revert back to it
parent::__construct();
//now, add the api version to the button_js, in order to force users to download the latest
//JS file
if(!$this->isDebugMode()){
$this->SHAREYOURCART_BUTTON_JS .= '?v='. $this->getConfigValue('api_version');
} else { //for debug mode, use a different JS ( one that is not minified, and can be cached thus debugged
$this->SHAREYOURCART_BUTTON_JS = $this->SHAREYOURCART_API.'/js/button.dev.js';
}
$this->SHAREYOURCART_BUTTON_URL .= '?client_id='. $this->getClientId();
//set the language & it's loader
SyC::setLanguageLoader(array(&$this,'loadLanguage'));
SyC::setLanguage($this->getConfigValue('lang'));
}
/**
* Execute NonQuery SQL
* @param string action
* @param string extra
* @return boolean
*/
protected abstract function executeNonQuery($sql);
/**
*
* Get the row returned from the SQL
*
* @return an associative array containing the data of the row OR NULL
* if there is none
*/
protected abstract function getRow($sql);
/**
* Abstract getTableName
* @param string key
*
*/
protected abstract function getTableName($key);
/**
* Abstract setConfigValue
* @param string option
* @param string value
* @return boolean
*/
protected abstract function setConfigValue($field, $value);
/**
* Abstract getConfigValue
* @param string option
* @param string value
* @return string
*/
protected abstract function getConfigValue($field);
/**
* Description: This returns an array with the details of the product
* displayed on this page. If it is not a product, it
* will return FALSE
* @remarks this will be mostly used by LITE integrations, so no need to make it mandatory
* @param null
* @return boolean / array
*/
protected function getCurrentProductDetails(){
return FALSE;
}
/**
*
* Return TRUE if this page describes a single product, otherwise FALSE
*
*/
protected abstract function isSingleProduct();
/**
*
* Return FALSE if the current single product is out of stock, or not
*
*/
public function isOutOfStock(){
return FALSE;
}
/**
*
* Return the URL to be called when the button is pressed
*
*/
protected abstract function getButtonCallbackURL();
/*
*
* Create url for the specified file. The file must be specified in relative path
* to the base of the plugin
*/
protected abstract function createUrl($file);
/**
*
* Called after the session has been reloaded
*
*/
protected abstract function loadSessionData();
/**
*
* Returns the plugin's secret key. This should be overwritten only by the actual plugin
*
*/
protected abstract function getSecretKey();
/**
*
* Insert a row in the table
* @param string tableName
* @param array data
*
*/
protected abstract function insertRow($tableName, $data);
/**
*
* Apply the coupon code
*
*/
protected abstract function applyCoupon($coupon_code);
/**
*
* Return the jQuery sibling selector for the product button
*
*/
protected function getProductButtonPosition(){
return $this->getConfigValue('product_button_position');
}
/**
*
* Return the jQuery sibling selector for the cart button
*
*/
protected function getCartButtonPosition(){
return $this->getConfigValue('cart_button_position');
}
/**
*
* Get the plugin version.
* @return an integer
*
*/
protected abstract function getPluginVersion();
/**
*
* Get the entire Version, including the SDK one
*
*/
public function getVersion()
{
//make sure a developer enters only a number as a version
if(!is_int($minor_version = $this->getPluginVersion()))
throw new Exception(SyC::t('sdk','The Plugin Version must be an integer'));
return self::$_SDK_VERSION.'.'.$minor_version;
}
/**
*
* Returns TRUE if the account is in debug mode
*
*/
public function isDebugMode()
{
$val =$this->getConfigValue('debug');
return !empty($val);
}
/**
*
* Return TRUE if there is a newer version of the plugin
*
*/
protected function hasNewerVersion()
{
return version_compare($this->getVersion(),$this->getConfigValue('latest_version'),'<');
}
/**
*
* Check if this instance can load, or not!
* This is meant so that at ALL times, only the latest plugin version will work
*
*/
protected function canLoad()
{
$v = version_compare($this->getVersion(),$this->getConfigValue('plugin_current_version'));
//first, check if this instance is the latest one, or not
if($v < 0) return false;
//save the latest version, for later reference
if($v > 0 )
$this->setConfigValue('plugin_current_version',$this->getVersion());
return true;
}
/**
* install the plugin
* @param null
* @return boolean
*/
public function install(&$message = null) {
//this is a single call function
if (!$this->isFirstCall(__FUNCTION__))
return;
//create the tokens table
$this->createTable($this->getTableName('shareyourcart_tokens'), array(
'id' => 'int(11)',
'token' => 'varchar(255)',
'session_id' => 'varchar(255)',
), 'id');
//create the coupon log table
$this->createTable($this->getTableName('shareyourcart_coupons'), array(
'id' => 'int(11)',
'token' => 'varchar(255)',
'coupon_id' => 'varchar(255)',
), 'id');
//save the DB version, for later use
$this->setConfigValue('db_version', self::$_DB_VERSION);
//if we have credentials in the DB, try to activate the plugin
//with them
$activated = false;
$appKey = $this->getAppKey();
$clientId = $this->getClientId();
if(!empty($appKey) && !empty($clientId)){
$activated = $this->activate($message);
}
//set some default value, like the button skin
$skin = $this->getConfigValue('button_skin');
if(empty($skin)){
$this->setConfigValue("button_skin", "light");
}
return true;
}
/**
* uninstall the plugin
* @param null
* @return boolean
*/
public function uninstall(&$message = null) {
//this is a single call function
if (!$this->isFirstCall(__FUNCTION__))
return;
//first, make sure we deactivate the plugin
$this->deactivate($message);
//remove the tables
$this->dropTable($this->getTableName('shareyourcart_tokens'));
$this->dropTable($this->getTableName('shareyourcart_coupons'));
//remove the db version
$this->setConfigValue('db_version', null);
return true;
}
/**
* activate the plugin
* @param null
* @return boolean
*/
public function activate(&$message = null) {
//this is a single call function
if (!$this->isFirstCall(__FUNCTION__))
return;
//active the API
if ($this->setAccountStatus($this->getSecretKey(), $this->getClientID(), $this->getAppKey(), true, $message) === TRUE) {
$this->setConfigValue("account_status", "active");
return true;
} else {
$this->setConfigValue("account_status", "inactive");
return false;
}
}
/**
* deactivate the plugin
* @param null
* @return boolean
*/
public function deactivate(&$message = null) {
//send the notification to the API
$success = $this->setAccountStatus($this->getSecretKey(), $this->getClientID(), $this->getAppKey(), false, $message);
//no matter what the API says, disable this plugin
$this->setConfigValue("account_status", "inactive");
return $success;
}
/**
* getAppKey
* @param null
* @return appKey
*/
public function getAppKey() {
return $this->getConfigValue('appKey');
}
/**
* getClientID
* @param null
* @return clientID
*/
public function getClientId() {
return $this->getConfigValue('clientId');
}
/**
* Check if the plugin is active, or not
* @param null
* @return boolean
*/
public function isActive() {
return ($this->getConfigValue('account_status') == "active");
}
/**
* startSession
* @param string $params
* @return boolean
*/
public function startSession($params) {
//make sure the params contain the required entries
if (!isset($params['app_key']))
$params['app_key'] = $this->getAppKey();
if (!isset($params['client_id']))
$params['client_id'] = $this->getClientId();
//create a new session
$data = parent::startSession($params);
//reset the Location, as the following code might give an error
//and the developer needs to be aware of it
$headers = headers_list();
header('Location:');
//save session details
$this->insertRow($this->getTableName('shareyourcart_tokens'), $data);
//we can't rely on the fact that the row has been inserted, so check!
if($this->getSessionId($data['token']) === null)
throw new Exception(SyC::t('sdk','Token cannot be saved. Check your "{table_name}" table permissions.', array('{table_name}' => $this->getTableName('shareyourcart_tokens'))));
//since everything is ok, resume the Location header
foreach($headers as $header)
{
header($header);
}
return true;
}
/**
* ensureCouponIsValid
* @param string $params
* @return boolean
*/
public function assertCouponIsValid($token, $coupon_code, $coupon_value, $coupon_type) {
//first call the parent function
parent::assertCouponIsValid($token, $coupon_code, $coupon_value, $coupon_type);
//get the session_id associated with the token
$session_id = $this->getSessionId($token);
//make sure the session is valid
if ($session_id === null) {
throw new Exception(SyC::t('sdk','Token not found'));
}
//resume the session
session_destroy();
session_id($session_id);
session_start();
$this->loadSessionData();
}
/**
* simply show the button
* @param null
* @return boolean
*/
public function showButton($position = null) {
echo $this->getButton($position);
}
/**
*
* get the button code
*
*/
public function getButton($position = null) {
//make sure the API is active
if(!$this->isActive()) return;
return $this->renderButton($this->getButtonCallbackURL(), $position);
}
/**
* renderButton
* @param null
* @return boolean
*/
protected function renderButton($callback_url,$position = null,$languageISO = null) {
$data = array(
'current_button_type' => $this->getConfigValue("button_type"),
'button_html' => $this->getConfigValue("button_html"),
'button_img' => $this->getUrl($this->getConfigValue("btn-img")),
'button_img_width' => $this->getConfigValue("btn-img-width"),
'button_img_height' => $this->getConfigValue("btn-img-height"),
'button_img_hover' => $this->getUrl($this->getConfigValue("btn-img-h")),
'button_img_hover_width' => $this->getConfigValue("btn-img-h-width"),
'button_img_hover_height' => $this->getConfigValue("btn-img-h-height"),
'is_product_page' => $this->isSingleProduct(),
'position_'.(SyC::startsWith($position,"/*before*/") ? 'before' : 'after') => $position,
'language' => $languageISO,
);
$output = null;
switch ($data['current_button_type'])
{
case '1':
$output = $this->renderView('button',$data);
break;
case '2':
$output = $this->renderView('button-img',$data);
break;
case '3':
$output = $this->renderView('button-custom',$data);
break;
default:
$output = $this->renderView('button',$data);
break;
}
return $output;
}
/**
*
* show the button on a product page
*
*/
public function showProductButton() {
echo $this->getProductButton();
}
/**
*
* get the button for a product page
*
*/
public function getProductButton() {
if($this->isSingleProduct() && !$this->getConfigValue('hide_on_product') && !$this->isOutOfStock()){
return $this->getButton($this->getProductButtonPosition());
}
//else return nothing
return null;
}
/**
*
* show the button on a cart page
*
*/
public function showCartButton() {
echo $this->getCartButton();
}
/**
*
* get the button for the cart page
*
*/
public function getCartButton() {
if(!$this->getConfigValue('hide_on_checkout')){
return $this->getButton($this->getCartButtonPosition(),false);
}
//return nothing
return null;
}
/**
*
* Simply show the page header
*
*/
public function showPageHeader() {
echo $this->getPageHeader();
}
/**
* Get the page header code
* @param null
* @return boolean
*/
public function getPageHeader() {
//this is a single call function
if (!$this->isFirstCall(__FUNCTION__))
return;
return $this->renderView('page-header',array(
'data' => $this->getCurrentProductDetails(),
));
}
/**
* Show the admin header code
* @param null
* @return boolean
*/
public function showAdminHeader() {
echo $this->getAdminHeader();
}
/**
* Get the admin header code
* @param null
* @return boolean
*/
public function getAdminHeader() {
//this is a single call function
if (!$this->isFirstCall(__FUNCTION__))
return;
//check the SDK status
$this->checkSDKStatus(true); //force a check, as the admin might have changed the language in the configure page, so we need to sync with it
return $this->renderView('admin-header');
}
/**
* show the admin page
* @param null
* @return boolean
*/
public function showAdminPage($html='',$show_header=TRUE,$show_footer=TRUE) {
echo $this->getAdminPage($html,$show_header,$show_footer);
}
/**
*
* get the admin page
*
*/
public function getAdminPage($html='',$show_header=TRUE,$show_footer=TRUE) {
//this is a single call function
if (!$this->isFirstCall(__FUNCTION__))
return;
$status_message = ''; //this is to be used for good messages
$error_message = ''; //this is to be used for bad messages
$refresh = false;
//check if this is a post for this particular page
if ($_SERVER['REQUEST_METHOD'] == 'POST' &&
!empty($_POST['syc-account-form'])) {
$this->setConfigValue('appKey', $_POST['app_key']);
$this->setConfigValue('clientId', $_POST['client_id']);
//it is vital that we call the activation API here, to make sure, that the account is ACTIVE
//call the account status function
$message = '';
if ($this->activate($message) == true) {
$status_message = SyC::t('sdk','Account settings successfully saved');
} else {
//the account did not activate, so show the error
$error_message = $message;
}
//since we might have changed the status, REFRESH
$refresh = true;
}
//the user decided to disable the API
else if ($_SERVER['REQUEST_METHOD'] == 'POST' &&
!empty($_POST['disable-API'])){
$message = '';
if($this->deactivate($message) == true) {
$status_message = $message;
} else {
$error_message = $message;
}
//since we might have changed the status, REFRESH
$refresh = true;
}
//the user decided to activate the API
else if ($_SERVER['REQUEST_METHOD'] == 'POST' &&
!empty($_POST['enable-API'])){
$message = '';
if($this->activate($message) == true) {
$status_message = $message;
} else {
$error_message = $message;
}
//since we might have changed the status, REFRESH
$refresh = true;
}
//check if the user wants to recover his account
else if (@$_REQUEST['syc-account'] === 'recover'){
//by default, show the form if we are here
$show_form = true;
if($_SERVER['REQUEST_METHOD'] == 'POST' &&
!empty($_POST['syc-recover-account']))
{
//try to recover if the user posted the form
$show_form = !$this->recover($this->getSecretKey(), @$_REQUEST['domain'], @$_REQUEST['email'], $status_message);
}
//if we need to show the form, the recovery failed
if($show_form)
{
//if there is a message, put the form on a new line
$error_message = $status_message;
$status_message = $this->renderView('account-recover-partial', array(
'html' => $html,
));
}
else
{
//Refresh in order to get rid of the GET parameter
$refresh = true;
}
}
else if (@$_REQUEST['syc-account'] === 'create'){
//by default, show the form if we are here
$show_form = true;
if($_SERVER['REQUEST_METHOD'] == 'POST' &&
!empty($_POST['syc-create-account']))
{
//first, check if the user has agreed to the terms and conditions
if(isset($_POST['syc-terms-agreement']))
{
//try to create the account if the user posted the form
if (!(($register = $this->register($this->getSecretKey(), @$_REQUEST['domain'], @$_REQUEST['email'], $status_message)) === false))
{
$this->setConfigValue('appKey', @$register['app_key']);
$this->setConfigValue('clientId', @$register['client_id']);
$this->setConfigValue("account_status", "active");
$show_form = false; //no need to show the register form anymore
//since we might have changed the status, REFRESH
$refresh = true;
}
}
else
{
//put it in the status message, as it will be moved to error_message in the following IF
$status_message = SyC::t('sdk',"Error. You must agree with the terms and conditions bellow");
}
}
//if we need to show the form
if($show_form)
{
//move any message to errors
$error_message = $status_message;
$status_message = $this->renderView('account-create-partial', array(
'html' => $html,
));
}
}
//make sure there is a session variable setup
@session_start();
//since switching the API status has a great impact on how the UI looks, refresh the page
//just to make sure the UI is using the latest value
if($refresh)
{
//make sure to save the messages
$_SESSION['_syc_status_message'] = $status_message;
$_SESSION['_syc_error_message'] = $error_message;
}
else
{
//load the variables, if any
//if there is a status message
if(!empty($_SESSION['_syc_status_message']))
{
$status_message = $_SESSION['_syc_status_message'];
unset($_SESSION['_syc_status_message']);
}
//if there is an error message
if(!empty($_SESSION['_syc_error_message']))
{
$error_message = $_SESSION['_syc_error_message'];
unset($_SESSION['_syc_error_message']);
}
}
// Display the view
return $this->renderView('admin-page',array(
'html' => $html,
'show_header' => $show_header,
'show_footer' => $show_footer,
'status_message' => $status_message,
'error_message' => $error_message,
'refresh' => $refresh,
));
}
/**
*
* show page to customize the button
*
*/
public function showButtonCustomizationPage($html='',$show_header=TRUE,$show_footer=TRUE) {
echo $this->getButtonCustomizationPage($html,$show_header,$show_footer);
}
/**
*
* get the page to customize the button
*
*/
public function getButtonCustomizationPage($html='',$show_header=TRUE,$show_footer=TRUE){
//if visual settings are submitted
if ($_SERVER['REQUEST_METHOD'] == 'POST' &&
!empty($_POST['syc-visual-form'])) {
//set the button declaration
$this->setConfigValue("button_type", $_POST['button_type']);
//set the button skin
$this->setConfigValue("button_skin", $_POST['button_skin']);
//set the button position
$this->setConfigValue("button_position", $_POST['button_position']);
//set the button height
$this->setConfigValue("dont_set_height", empty($_POST['show_on_single_row']));
//set the button html
$this->setConfigValue("button_html", rawurldecode($_POST['button_html']));
//set the show
$this->setConfigValue("hide_on_product", empty($_POST['show_on_product']));
//set the show'
$this->setConfigValue("hide_on_checkout", empty($_POST['show_on_checkout']));
//set button position
$this->setConfigValue("product_button_position",$_POST['product_button_position']);
$this->setConfigValue("cart_button_position",$_POST['cart_button_position']);
if($_FILES["button-img"]["name"]!='') {
$target_path = $this->getUploadDir();
if(!SyC::endsWith($target_path,'/')) $target_path .= '/'; //make sure that the path has a / in it's end
$target_path = $target_path . 'button-img.png';
if(file_exists($target_path)) unlink($target_path);
list($width, $height, $type, $attr) = getimagesize($_FILES['button-img']['tmp_name']);
if (move_uploaded_file($_FILES['button-img']['tmp_name'], $target_path))
{
//set the button img
$this->setConfigValue("btn-img", $this->getUrl($target_path));
$this->setConfigValue("btn-img-width", $width);
$this->setConfigValue("btn-img-height", $height);
}
else
{
//upload failed, so notify the user
throw new Exception(SyC::t('sdk','Cannot upload image to directory {directory}. Check the permissions',array('{directory}',$this->getUploadDir())));
}
}
if($_FILES["button-img-hover"]["name"]!='') {
$target_path = $this->getUploadDir();
if(!SyC::endsWith($target_path,'/')) $target_path .= '/'; //make sure that the path has a / in it's end
$target_path = $target_path . 'btn-img-hover.png';
if(file_exists($target_path)) unlink($target_path);
list($width, $height, $type, $attr) = getimagesize($_FILES['button-img-hover']['tmp_name']);
if(move_uploaded_file($_FILES['button-img-hover']['tmp_name'], $target_path))
{
//set the show'
$this->setConfigValue("btn-img-h", $this->getUrl($target_path));
$this->setConfigValue("btn-img-h-width", $width);
$this->setConfigValue("btn-img-h-height", $height);
}
else
{
//upload failed, so notify the user
throw new Exception(SyC::t('sdk','Cannot upload image to directory {directory}. Check the permissions',array('{directory}',$this->getUploadDir())));
}
}
$status_message = SyC::t('sdk','Button settings successfully updated.');
}
//render the view
return $this->renderView('button-settings-page', array(
'current_button_type' => $this->getConfigValue("button_type"),
'current_skin' => $this->getConfigValue("button_skin"),
'current_position' => $this->getConfigValue("button_position"),
'show_on_checkout' => !$this->getConfigValue("hide_on_checkout"),
'show_on_product' => !$this->getConfigValue("hide_on_product"),
'show_on_single_row' => !$this->getConfigValue("dont_set_height"),
'button_html' => $this->getConfigValue("button_html"),
'button_img' => $this->getUrl($this->getConfigValue("btn-img")),
'button_img_hover' => $this->getUrl($this->getConfigValue("btn-img-h")),
'html' => $html,
'show_header' => $show_header,
'show_footer' => $show_footer,
'status_message' => @$status_message,
));
}
/**
*
* Override this function and provide a writable folder to upload
* the files to
*
*/
public function getUploadDir(){
return dirname(_FILE_). "/img/";
}
/**
* showDocumentation
* @param null
* @return boolean
*/
public function showDocumentationPage($html='',$show_header=TRUE,$show_footer=TRUE) {
echo $this->getDocumentationPage($html,$show_header,$show_footer);
}
/**
* get the documentation page
* @param null
* @return boolean
*/
public function getDocumentationPage($html='',$show_header=TRUE,$show_footer=TRUE) {
//this is a single call function
if (!$this->isFirstCall(__FUNCTION__))
return;
//render the view
return $this->renderView('documentation',array(
'action_url' => $this->getButtonCallbackURL(),
'html' => $html,
'show_header' => $show_header,
'show_footer' => $show_footer,
));
}
/**
* show the update notification
* @param null
*/
public function showUpdateNotification(){
echo $this->getUpdateNotification();
}
/**
* get the update notification
* @param null
*/
public function getUpdateNotification(){
//render the view
return $this->renderView('update-notification-partial');
}
/*
*
* Called when a new coupon is generated
*
*/
public function couponCallback() {
try {
/* * ********* Check input parameters ******************************* */
if (!isset($_POST['token'], $_POST['coupon_code'], $_POST['coupon_value'], $_POST['coupon_type'])) {
throw new Exception(SyC::t('sdk','At least one of the parameters is missing. Received: {data}', array('{data}' => print_r($_POST, true))));
}
//make sure the coupon is valid
$this->assertCouponIsValid($_POST['token'], $_POST['coupon_code'], $_POST['coupon_value'], $_POST['coupon_type']);
//save the coupon
$this->saveCoupon($_POST['token'], $_POST['coupon_code'], $_POST['coupon_value'], $_POST['coupon_type'], (isset($_POST['product_unique_ids']) && is_array($_POST['product_unique_ids']) ? $_POST['product_unique_ids'] : array()));
//check if the coupon is intended to be applied to the current cart
if (empty($_POST['save_only'])) {
$this->applyCoupon($_POST['coupon_code']);
}
} catch (Exception $e) {
header("HTTP/1.0 403");
echo $e->getMessage();
if($this->isDebugMode()){
echo $e->getTraceAsString();
}
}
}
/**
* Save the coupon
* @param null
* @return boolean
*/
protected function saveCoupon($token, $coupon_code, $coupon_value, $coupon_type, $product_unique_ids = array()) {
//add the coupon id in shareyourcart coupons table
$data = array(
'token' => $token,
'coupon_id' => $coupon_code,
);
$this->insertRow($this->getTableName('shareyourcart_coupons'), $data);
}
/**
*
* Based on the token, get the session_id
*
*/
protected function getSessionId($token) {
$result = $this->getRow("SELECT session_id FROM " . $this->getTableName('shareyourcart_tokens') . " WHERE token='$token'");
return isset($result) ? $result['session_id'] : null;
}
/**
*
* createTable
* @param table
* @param array columns
* @param string @option
*/
protected function createTable($tableName, $columns, $primaryKey, $options=NULL) {
$sql = "CREATE TABLE IF NOT EXISTS $tableName (\n ";
foreach ($columns as $name => $type) {
$sql .= "$name $type";
if ($name == $primaryKey) {
$sql .= " NOT NULL AUTO_INCREMENT";
}
$sql .= ",\n ";
}
$sql .= "PRIMARY KEY ($primaryKey));";
$this->executeNonQuery($sql);
//we can't rely on the fact that the table has been properly created, so check it!
if(!$this->existsTable($tableName))
throw new Exception(SyC::t('sdk','Cannot create table "{table_name}". Check your database permissions or manually run the following SQL command and try again:<br /><strong>{sql}</strong>', array('{table_name}' => $tableName,'{sql}' => nl2br($sql))));
}
/**
*
* existsTable
* @return TRUE if the table exists, otherwise false
*/
protected function existsTable($tableName){
$table_details = $this->getRow("show tables like '$tableName'");
//if there are table details, it means the table exists
return !empty($table_details);
}
/**
* Drop the specified table
*
* @param string tableName
*/
protected function dropTable($tableName) {
$sql = "DROP TABLE $tableName";
$this->executeNonQuery($sql);
//we can't rely on the fact that the table has been properly dropped, so check it!
if($this->existsTable($tableName))
throw new Exception(SyC::t('sdk','Cannot drop table "{table_name}". Check your database permissions or manually run the following SQL command and try again:<br /><strong>{sql}</strong>', array('{table_name}' => $tableName, '{sql}' => nl2br($sql))));
}
/**
*
* Render the specified views. we use special variable names here to avoid conflict when extracting data
*
*/
protected function renderView($_viewName_, $_data_=NULL, $_return_=true){
//get information about the Top Parent class
$_reflection_ = new ReflectionClass(get_class($this));
$_viewFile_ = dirname($_reflection_->getFileName())."/views/$_viewName_.php";
//check if there is a file in the specified location
if(!file_exists($_viewFile_)){
//the view has not been overridden, so use the SDK one
$_viewFile_ = dirname(__FILE__) . "/views/$_viewName_.php";
}
//extract the data
if(is_array($_data_))
extract($_data_,EXTR_PREFIX_SAME,'data');
else
$data=$_data_;
//render the view
if($_return_)
{
ob_start();
ob_implicit_flush(false);
require($_viewFile_);
return ob_get_clean();
}
else
require($_viewFile_);
}
/**
*
* This function is used to make sure that the created url returns a proper scheme
*
*/
protected function getUrl($file){
//if there is no file, return an empty string
if(empty($file)) return $file;
//test if the files is a url, as one migt send it that way
$parts = parse_url($file);
$is_url = is_array($parts) && isset($parts['scheme']) && SyC::startsWith($parts['scheme'],'http');
//if this is not a url, create one for it
if(!$is_url)
{
//as we can't control what if the developers
//will take care of the HTTP / HTTPS matching,
$url = $this->createUrl($file);
}
else
{
$url = $file;
}
//do it here. the problem is loading an insecure object over a secure page, so check for this situation
if( (isset($_SERVER['HTTPS']) && !strcasecmp($_SERVER['HTTPS'],'on')) && //the page is a secure one
SyC::startsWith($url,'http://') //the created url is an insecure one, adjust it
)
{
$url = "https://".substr($url, 7);
}
return $url;
}
/**
*
* Check the SDK status
* @param $force. TRUE to check, no matter how soon the previous check was. This can have a great impact on the experience of the admin
*
*/
public function checkSDKStatus($force = false) {
//call the API at most only once every 5 minutes, not sooner
if(!$force && (time()-$this->getConfigValue('api_last_check')) < 5*60)
return;
//set the latest check time
$this->setConfigValue('api_last_check',time());
//get an update from the API
$message = '';
if(is_array($result = $this->getSDKStatus($this->getSecretKey(), $this->getClientId(), $this->getAppKey(), $message)))
{
//save the data
$this->setConfigValue('api_version', @$result['api_version']);
$this->setConfigValue('latest_version', @$result['plugin_latest_version']);
$this->setConfigValue('download_url', @$result['plugin_download_url']);
$this->setConfigValue('debug', @$result['debug']);
//set the current language the SDK should be displayed in
if(isset($result['lang'])){
$this->setConfigValue('lang', $result['lang']);
SyC::setLanguage($result['lang']);
//check if there is a new translation available for this language
if(!empty($result['lang_checksum']) && $result['lang_checksum'] != SyC::getLanguageChecksum()){
//download the translation
$messages = $this->getSDKTranslation(SyC::getLanguage());
//save the translation
$this->setConfigValue('messages', $messages);
//reset the loaded messages so that the new ones are being used
SyC::reloadLanguage();
}
}
}else{
//simply log the error, for now!
error_log(print_r($message,true));
}
}
/**
*
* Language loader ( from the DB )
*
*/
public function loadLanguage($lang, $category)
{
//see if we have the language saved in the db
$messages = $this->getConfigValue('messages');
if(empty($messages)) //no language is saved, so revert to the file one
{
$messages = SyC::loadFileLanguage($lang,$category);
}
//make sure we have an array for this variable
if(!is_array($messages)) $messages=array();
return $messages;
}
/*
*
* Call to see if the function was called once, or not
*
*/
protected static function isFirstCall($functionName) {
if (array_key_exists($functionName, self::$_SINGLE_FUNCTIONS_CALLS))
return false;
self::$_SINGLE_FUNCTIONS_CALLS[$functionName] = true;
return true;
}
/**
*
* User to catch any unhandled exceptions and print them nicely
*
*/
public function UncaughtExceptionHandler(Exception $e) {
//@header("HTTP/1.0 403");
echo $e->getMessage();
if($this->isDebugMode()){
echo $e->getTraceAsString();
}
}
}
} //END IF
?>