SOAP request taking too long to process large data - php

I get an array from other website with helping SOAP client, it's quite big array, you can check it out short version here
An array
I need to get category names, my code is here, it works but slows website down. if anyone can provide better code.
$client = new nusoap_client('http://87.253.63.146/b2b/b2bWS?WSDL', 'wsdl');
$client->soap_defencoding = 'UTF-8';
$client->decode_utf8 = false;
$parametrebi = array('user' => '','brand' => '', 'vat_zone' => 'GEVAT', 'currency' => 'GEL', 'all_items' => 'Y', 'page_num' => '1', 'lines_per_page' => '25');
$result = $client->call('GetPriceList', $parametrebi, array('return' => 'xsd:string'), "");
foreach($result['PriceList']['categories']['category'] as $category)
{
echo '<option value="'.$category['!id'].'">'.$category['!name'].'</option>';
}

Do the categories change that often?
Cant you poll for the categories every so often?
Eg every 5 min or so make this soap call and either save the categories to a table in the DB (not such a good idea) or memcache.
http://memcached.org/
If you can use memcache...here is a ruff example:
$memcache_obj = new Memcache();
$memcache_obj->connect('memcache_host', 11211);
if(!$categories = $memcache_obj->get('soap_categories')) {
$client = new nusoap_client('http://87.253.63.146/b2b/b2bWS?WSDL', 'wsdl');
$client->soap_defencoding = 'UTF-8';
$client->decode_utf8 = false;
$parametrebi = array('user' => '','brand' => '', 'vat_zone' => 'GEVAT', 'currency' => 'GEL', 'all_items' => 'Y', 'page_num' => '1', 'lines_per_page' => '25');
$result = $client->call('GetPriceList', $parametrebi, array('return' => 'xsd:string'), "");
$categories = $result['PriceList']['categories']['category'];
$memcache_obj->set('soap_categories', $categories)
}
foreach($categories as $category)
{
echo '<option value="'.$category['!id'].'">'.$category['!name'].'</option>';
}
You can set the expire time on memcache to 1,2,5...ect minuites so the categories will be updated every time the cache expires. Other then when the cache expires the lookup time will be less then 5-10ms.

Related

Is there a way to handle large arrays of colums from MySQL when importing via $POST

I am trying to work on a API to import data to MySQL Database.
I have it working on a small scale.
I have now altered it so its more in line with the current database. Its a large table and been poorly structured, But for simplicity and maintaining am trying to keep MySQL database and the Applications database inline.
MSQL = Windows based application:
MySQL = The Server database, Am extracting Data out of MSQL hosted locally and importing it to a MySQL Database hosted externally.
As i have expanded the code, its no longer working, this could be a number of factors like the table needs structuring / indexing / primary, or i am passing too much data via a query. The application is starting to look very messy.
The question is, is it necessary and better practice me listing out each column and matching up the data sets apposed to trying to utilize the MySQL INFORMATION_SCHEMA to list the columns instead.
Here is the code so far, I have already removed a number of columns.
We have a Server and Host:
Server Code
Class file: Api.php
class API
{
private $connect = '';
function __construct()
{
$this->database_connection();
}
function database_connection()
{
$this->connect = new PDO("mysql:host=$Host;dbname=$DatabaseName", $DatabaseUsername, $DatabasePassword);
}
function insert() // Insert Function
{
if(isset($_POST["Branch"]))
{
$form_data = array(
':Branch'=>$_POST['Branch'],
':Date'=>$_POST['Date'],
':Week'=>$_POST['Week'],
':Period'=>$_POST['Period'],
':Invoice_No'=>$_POST['Invoice_No'],
':Invoice_Reference'=>$_POST['Invoice_Reference'],
':Line_No'=>$_POST['Line_No'],
':Till_No'=>$_POST['Till_No'],
':Operator'=>$_POST['Operator'],
':Stock_Code'=>$_POST['Stock_Code'],
':Barcode'=>$_POST['Barcode'],
':Line_Quantity'=>$_POST['Line_Quantity'],
':Weight'=>$_POST['Weight'],
':Weight_Unit'=>$_POST['Weight_Unit'],
':Man_Weighed'=>$_POST['Man_Weighed'],
':Unit_ID'=>$_POST['Unit_ID'],
':Line_Price_Band'=>$_POST['Line_Price_Band'],
':Original_Sell'=>$_POST['Original_Sell'],
':Actual_Sell'=>$_POST['Actual_Sell'],
':Cost'=>$_POST['Cost'],
':Vat_Rate'=>$_POST['Vat_Rate'],
':Discount_Rate'=>$_POST['Discount_Rate'],
':Value_Goods'=>$_POST['Value_Goods'],
':Value_VAT'=>$_POST['Value_VAT'],
':Value_Sale'=>$_POST['Value_Sale'],
':Value_Cost'=>$_POST['Value_Cost'],
':Price_Override_Amount'=>$_POST['Price_Override_Amount'],
':Price_Overrided'=>$_POST['Price_Overrided'],
':Discounted'=>$_POST['Discounted'],
':Account_No'=>$_POST['Account_No'],
':Sub_Account_No'=>$_POST['Sub_Account_No'],
':Customer_Account'=>$_POST['Customer_Account'],
':Sub_Customer_Account'=>$_POST['Sub_Customer_Account'],
':Cust_Type_ID'=>$_POST['Cust_Type_ID'],
':Super_Department_ID'=>$_POST['Super_Department_ID'],
':Department_ID'=>$_POST['Department_ID'],
':Group_ID'=>$_POST['Group_ID'],
':Sub_Group_ID'=>$_POST['Sub_Group_ID'],
':Retail_Location_ID'=>$_POST['Retail_Location_ID'],
':Retail_Sub_Location_ID'=>$_POST['Retail_Sub_Location_ID'],
':Entry_Method'=>$_POST['Entry_Method'],
':End_Sale_Discount_Rate'=>$_POST['End_Sale_Discount_Rate'],
':Loyalty_Discount_Rate'=>$_POST['Loyalty_Discount_Rate'],
':Date_Time_Stamp'=>$_POST['Date_Time_Stamp']
);
$query = "
INSERT INTO Lines
(Branch, Date, Week, Period, Invoice_No, Invoice_Reference, Line_No, Till_No, Operator, Stock_Code, Barcode, Line_Quantity, Weight, Weight_Unit, Man_Weighed, Unit_ID, Line_Price_Band, Original_Sell, Actual_Sell, Cost, Vat_Rate, Discount_Rate, Value_Goods, Value_VAT, Value_Sale, Value_Cost, Price_Override_Amount, Price_Overrided, Discounted, Account_No, Sub_Account_No, Customer_Account, Sub_Customer_Account, Cust_Type_ID, Super_Department_ID, Department_ID, Group_ID, Sub_Group_ID, Retail_Location_ID, Retail_Sub_Location_ID, Entry_Method, End_Sale_Discount_Rate, Loyalty_Discount_Rate, Date_Time_Stamp) VALUES
(:Branch, :Date, :Week, :Period, :Invoice_No, :Invoice_Reference, :Line_No, :Till_No, :Operator, :Stock_Code, :Barcode, :Line_Quantity, :Weight, :Weight_Unit, :Man_Weighed, :Unit_ID, :Line_Price_Band, :Original_Sell, :Actual_Sell, :Cost, :Vat_Rate, :Discount_Rate, :Value_Goods, :Value_VAT, :Value_Sale, :Value_Cost, :Price_Override_Amount, :Price_Overrided, :Discounted, :Account_No, :Sub_Account_No, :Customer_Account, :Sub_Customer_Account, :Cust_Type_ID, :Super_Department_ID, :Department_ID, :Group_ID, :Sub_Group_ID, :Retail_Location_ID, :Retail_Sub_Location_ID, :Entry_Method, :End_Sale_Discount_Rate, :Loyalty_Discount_Rate, :Date_Time_Stamp)
";
$statement = $this->connect->prepare($query);
if($statement->execute($form_data))
{
echo $statement ;
$data[] = array(
'success' => '1'
);
}
else
{
var_dump($statement) ;
$data[] = array(
'success' => '0'
);
}
}
else
{
$data[] = array(
'success' => '0'
);
}
return $data;
}
}
Calling the Function: Handler test_api.php
// This does have an include for Api.php
if($_GET["action"] == 'insert')
{
$data = $api_object->insert();
}
Host code
This wont be the final thing, as ill be extracting from MSQL building the array and posting this way, This is just laid out like so for testing
<?php
$form_data = array(
'Branch' => '1',
'Date' => '8/11/2018 13:42:00',
'Week' => '1',
'Period' => '1',
'Invoice_No' => '9999998',
'Invoice_Reference' => '99999998',
'Line_No' => '1',
'Till_No' => '1',
'Operator' => '99',
'Stock_Code' => '123456',
'Barcode' => '654321',
'Line_Quantity' => '99',
'Weight' => '',
'Weight_Unit' => '',
'Man_Weighed' => '',
'Unit_ID' => '',
'Line_Price_Band' => '1',
'Original_Sell' => '99.99',
'Actual_Sell' => '99.99',
'Cost' => '9.99',
'Vat_Rate' => '1',
'Discount_Rate' => '',
'Value_Goods' => '',
'Value_VAT' => '',
'Value_Sale' => '',
'Value_Cost' => '',
'Price_Override_Amount' => '',
'Price_Overrided' => '',
'Discounted' => '',
'Account_No' => '',
'Sub_Account_No' => '',
'Customer_Account' => '',
'Sub_Customer_Account' => '',
'Cust_Type_ID' => '',
'Super_Department_ID' => '',
'Department_ID' => '',
'Group_ID' => '',
'Sub_Group_ID' => '',
'Retail_Location_ID' => '',
'Retail_Sub_Location_ID' => '',
'Entry_Method' => '',
'End_Sale_Discount_Rate' => '',
'Loyalty_Discount_Rate' => '',
'Date_Time_Stamp' => ''
);
$api_url = "localhost/Modules/API/Server/test_api.php?action=insert"; //change this url as per your folder path for api folder
$client = curl_init($api_url);
curl_setopt($client, CURLOPT_POST, true);
curl_setopt($client, CURLOPT_POSTFIELDS, $form_data);
curl_setopt($client, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($client);
// var_dump($response);
curl_close($client);
$result = json_decode($response, true);
echo $response ;
foreach($result as $keys => $values)
{
if($result[$keys]['success'] == '1')
{
echo 'update';
}
else
{
echo 'error';
echo $response ;
}
}
At the moment its not working, I am not sure why, As it was working fine with a much smaller dataset.
And my IDE hasnt reported of any errors or typos, But thats something else, if you do spot a error, please do say.
The question is, is there a better way to work with large number of columns.
In previous API's i have basically just dumped the data to txt and imported from a deliminator. So this is all very new to me.

500 error when trying to add new order in TradeGecko API

Pretty specific problem, but I'll lay it out as best I can.
I can easily make a POST request to the TradeGecko API (detailed here: http://developer.tradegecko.com/) and get variant prices in return, that part of the interaction is working smoothly.
However, I'm trying to create a new order and I feel like I'm missing something!
Here's what I have:
<?php
$authorizeUrl = 'https://api.tradegecko.com/oauth/authorize';
$accessTokenUrl = 'https://api.tradegecko.com/oauth/token';
$clientId = <MY_CLIENT_ID>;
$clientSecret = <MY_CLIENT_SECRET>;
$redirectUrl = <REDIRECT_URI>;
// https://github.com/adoy/PHP-OAuth2
require("Client.php");
require("GrantType/IGrantType.php");
require("GrantType/AuthorizationCode.php");
$client = new OAuth2\Client($clientId, $clientSecret, OAuth2\Client::AUTH_TYPE_AUTHORIZATION_BASIC);
$client->setCurlOption(CURLOPT_USERAGENT,$userAgent);
$client->setAccessToken(<MY_ACCESS_TOKEN>);
$client->setAccessTokenType(OAuth2\Client::ACCESS_TOKEN_BEARER);
$params =
array('order' =>
array(
'company_id' => '12345',
'shipping_address_id' => 1,
'billing_address_id' => 1,
'status' => 'active',
'issued_at' => '10-04-2016',
'order_line_items' => array(
array('variant_id' => 123456,
'quantity' => 2),
array('variant_id' => 123457,
'quantity' => 2)
)
)
);
$response = $client->fetch('https://api.tradegecko.com/orders', false, $params);
print_r($response);
?>
I'm hoping that there's something in that code that someone else might spot, I've been staring at it for the better part of 6 hours now, and I can't figure out why this won't go through.

NuSoap, XML was empty, couldn't parse

First, I have to say that I am totally new to WSDL-based Web Services using NuSOAP. I am trying to return an array of friends list from my soap server. Please find below my code listings as is:
Server:
//File includes omitted
function getFriendList($test = ''){
$results = array();
$results[] = array('name' => 'XXXXA1', 'surname' => 'XXXXA2');
$results[] = array('name' => 'XXXXXB1', 'surname' => 'XXXXB2');
$results[] = array('name' => 'XXXXXC1', 'surname' => 'XXXXC2');
return $results;
}
//Create server instance
$server = new soap_server();
//Configure our WSDL
$server->configureWSDL('server', 'urn:server');
//Add our Complex Type data type since we want to return an array
$server->wsdl->addComplexType(
'Friend',
'complexType',
'struct',
'all',
'',
array(
'name' => array('name' => 'name', 'type' => 'xsd:string'),
'surname' => array('name' => 'surname', 'type' => 'xsd:string')
)
);
//Register our array as a response
$server->wsdl->addComplexType(
'FriendArray',
'complexType',
'array',
'',
'SOAP-ENC:Array',
array(),
array(
array('ref' => 'SOAP-ENC:arrayType', 'wsdl:arrayType' => 'tns:Friend[]')
),
'tns:Friend'
);
//Register the actual function that retuns the array but in the
//return n field specify the complex type of array we added onto the wsdl
$server->register('getFriendList',
array('test' => 'xsd:string'),
array('return' => 'tns:FriendArray'),
'urn:server',
'urn:server#getFriendList',
'document',
'encoded',
'Fetch a list of friends as an array. If you\'re not here sorry.'
);
//Serve the service
$server->service($HTTP_RAW_POST_DATA = (!isset($HTTP_RAW_POST_DATA)) ? $HTTP_RAW_POST_DATA : '');
With this, I hoped that I did everything correctly. I followed the standard procedure to make it work but in vein.
On the client side, I used the soap address url in wsdl and appended it with "?wsdl", so that it give me wsdl file dynamically.
example:
//Client call
$client = new nusoap_client("http://soapserver.dev/webroot/part_three/server.php?wsdl", true);
I have also taken labour of adding some whistles and bells on my client object as shown below:
$client->soap_defencoding = 'UTF-8';
$client->decode_utf8 = false;
This doesn't seem to help at all. I had experienced an issue earlier since my function accepts no parameter, where my service died because I didnt pass any parameter that speaks of inputs in my $client->call($name, $in, $out). I ended up providing an empty array and I got this error.
Could this be related to the rpc/document parameter types of the register function?
Even using the wsdl file which I saved from my server url, I got the same error.
Can somebody please help me out here? Please!

Storing key value dictionary in Elgg

I am working on a plugin for Elgg that keeps track of device ids that are sent to the application when logging in from your mobile phone. For this, I would like to store these device ids in the database and would like to use ElggObjects for this.
This is what I do now:
function initialize() {
$androidTokens = elgg_get_entities(array(
'type' => 'object',
'subtype' => 'androidTokens',
'limit' => 0
));
$iosTokens = elgg_get_entities(array(
'type' => 'object',
'subtype' => 'iosTokens',
'limit' => 0
));
if ($androidTokens == 0) {
$tokenObject = new ElggObject();
$tokenObject->subtype = 'androidTokens';
$tokenObject->tags = array();
$tokenObject->save();
}
if ($iosTokens == 0) {
$tokenObject = new ElggObject();
$tokenObject->subtype = 'iosTokens';
$tokenObject->tags = array();
$tokenObject->save();
}
}
So this generates two ElggObjects that hold ids for android and for ios devices, stored in the metadata field tags. This array of tags can however not be retrieved anymore. When I do:
$tokenObject = elgg_get_entities(array(
'type' => 'object',
'subtype' => $os.'Tokens',
'limit' => 0
));
$tokens = $tokenObject->tags
tokens remains empty. Does someone know what I am doing wrong? Am I using the Elgg objects wrong?
I think the reason you're running into issues there is that elgg_get_entities returns an array of entities.
Am I correct in assuming that you'll only ever have one of each token object subtype? (One for iOS and one for Android?)
If so, I would modify your code as follows:
function initialize() {
$androidTokens = elgg_get_entities(array(
'type' => 'object',
'subtype' => 'androidTokens',
'limit' => 1 // only expecting one entity
));
$iosTokens = elgg_get_entities(array(
'type' => 'object',
'subtype' => 'iosTokens',
'limit' => 1 // only expecting one entity
));
if (count($androidTokens) == 0) {
$tokenObject = new ElggObject();
$tokenObject->subtype = 'androidTokens';
$tokenObject->tags = array();
$tokenObject->save();
}
if (count($iosTokens) == 0) {
$tokenObject = new ElggObject();
$tokenObject->subtype = 'iosTokens';
$tokenObject->tags = array();
$tokenObject->save();
}
}
Later, when grabbing the entity:
$tokenObject = elgg_get_entities(array(
'type' => 'object',
'subtype' => $os.'Tokens',
'limit' => 1 // only grab one
));
$tokens = $tokenObject[0]->tags; // get tag data for first (and only) entity

Prestashop error "invalid security token"

im creating a new module for prestashop 1.5.6 and im having some problems with it.
The module has to send sms to the costumers and it has to be an option of the back-Office menu.
I have created the module with the install and uninstall functions and added the tabs to the back-office menu, but im a newbie in prestashop so i don´t know how to make the AdminMyModuleController.php and when i try to click the tab of the module it says "INVALID SECURITY TOKEN", i don´t know how resolve this issue because i don´t know much of security.
If someone can add me on facebook or whatever to help me would be amazing.
Here is the code of the mymodule.php:
private function _createTab()
{
// Tab Raiz
$data = array(
'id_tab' => '',
'id_parent' => 0,
'class_name' => 'Empty',
'module' => 'mymodule',
'position' => 14, 'active' => 1
);
/* Insert the data to the tab table*/
$res = Db::getInstance()->insert('tab', $data);
//Get last insert id from db which will be the new tab id
$id_tabP = Db::getInstance()->Insert_ID();
//Define tab multi language data
$data_lang = array(
'id_tab' => $id_tabP,
'id_lang' => Configuration::get('PS_LANG_DEFAULT'),
'name' => 'SMS a clientes'
);
// Now insert the tab lang data
$res &= Db::getInstance()->insert('tab_lang', $data_lang);
// Tab Configuracion
$data = array(
'id_tab' => '',
'id_parent' => $id_tabP,
'class_name' => 'AdminMymodule',
'module' => 'mymodule',
'position' => 1, 'active' => 1
);
$res = Db::getInstance()->insert('tab', $data);
$id_tab = Db::getInstance()->Insert_ID();
$data_lang = array(
'id_tab' => $id_tab,
'id_lang' => Configuration::get('PS_LANG_DEFAULT'),
'name' => 'Configuracion'
);
$res &= Db::getInstance()->insert('tab_lang', $data_lang);
// Tab Enviar Sms
$data = array(
'id_tab' => '',
'id_parent' => $id_tabP,
'class_name' => 'AdminEnviar',
'module' => 'mymodule',
'position' => 1, 'active' => 1
);
$res = Db::getInstance()->insert('tab', $data);
$id_tab = Db::getInstance()->Insert_ID();
$data_lang = array(
'id_tab' => $id_tab,
'id_lang' => Configuration::get('PS_LANG_DEFAULT'),
'name' => 'Enviar SMS'
);
$res &= Db::getInstance()->insert('tab_lang', $data_lang);
return true;
}
Thanks
As Lliw said, you must use InstallModuleTab function.
private function installModuleTab($tabClass, $tabName, $idTabParent)
{
$pass = true;
$tab = new Tab();
$tab->name = $tabName;
$tab->class_name = $tabClass;
$tab->module = $this->name; // defined in __construct() function
$tab->id_parent = $idTabParent;
$pass = $tab->save();
return($pass);
}
You can put all in your Install function. For example for your first tab:
public function install()
{
if(!parent::install()
|| !$this->installModuleTab('Empty', array(1 => 'SMS a clientes'), $idTabParent = 0))
return false;
return true;
}
You can set languages with the following array:
array(1 => 'SMS a clientes', 2 => 'Language 2', 3 => 'Language 3')
Then you must create the AdminMyModuleController.php file
It's the wrong way to create a module tab. You should use this function in your install() :
$this->installModuleTab('AdminMyModule', array(1 => 'Attribute description'), $idTabParent = 9);
Then create an AdminMyModuleController.php in your module folder/controllers/admin/AdminMyModuleController.php
But you will need to set some function to see something displayed, i'll make a tutorial for that but until i do it, you can look in another admincontroller from the prestashop core and do the same.

Categories