Perl SOAP::LITE can parse array of object from WCF - arrays

I am having a small issue with the arrayed value from a WCF service. I have tested the WCF with WCF Storm. However I need it in perl. I can get the part of the object that is not in the array however when I try to get the arrayed values it seems to be jumping to the second value. Because I can see interface 2 but cannot see anything for the storage. Any advise it extremely helpful.
#!/usr/bin/perl
package main;
use SOAP::Lite;
# Variables
my $url = 'http://<MyServerName>/Services/DCSP/DCSP.ServerManagement.svc?wsdl';
my $url_debug = 'http://localhost:11040/Service1.svc?wsdl';
my $uri = 'http://tempuri.org/';
my $xmlns = 'http://schemas.datacontract.org/2004/07/WcfService1';
my $selectedOS = 'Solaris';
# Setup Network Connection
my $soap = SOAP::Lite
-> uri($uri)
-> on_action(sub { sprintf '%sIServerManagement/%s', #_ })
-> proxy($url)
->autotype(0)->readable(1);
my $response = $soap->serverExists(SOAP::Data->new(name => '_serverNamee', value => '<ServerName>'));
# Print the Result
if ($response->fault)
{
die $response->faultstring;
}
else
{
if($response->result > 0) {
my $serverID = $response->result;
my $buildserver = $soap->getServerById(SOAP::Data->new(name => '_id', value => $serverID));
my $cpus = $buildserver->valueof('//*/CPUs');
my $host = $buildserver->valueof('//*/Host');
my $hostname = $buildserver->valueof('//*/HostName');
my $memoryMB = $buildserver->valueof('//*/MemoryMB');
my $OS = $buildserver->valueof('//*/OperatingSystem');
my $stack = $buildserver->valueof('//*/Stack');
my $status = $buildserver->valueof('//*/Status');
my $tier = $buildserver->valueof('//*/Tier');
my $arch = $buildserver->valueof('//*/architecture');
my #interfaces = $buildserver->valueof('//*/*/systemInterface');
my #mounts = $buildserver->valueof('//*/*/systemStorage');
foreach $interface (#interfaces)
{
my $ipid = $interface->{'IPID'};
my $position = $interface->{'Position'};
my $ipaddress = $soap->getIpAddressByID(SOAP::Data->new(name => '_ID', value => $ipid));
my $gateway = $ipaddress->valueof('//*/gateway');
my $mask = $ipaddress->valueof('//*/mask');
my $vlan = $ipaddress->valueof('//*/vlanID');
my $ip = $ipaddress->valueof('//*/address');
}
foreach $mount (#mounts)
{
my $mountpoint = $mount->{'Anchor'};
my $size = $mount->{'SizeMB'};
}
}
}
Output from WCF Storm:
<getServerById>
<MethodParameters>
<virtualServer>
<systemInterface attr0="NetworkInterfaceArray" isNull="false">
<NetworkInterfaceArray0>
<IPID>4</IPID>
<Position>0</Position>
<SystemID>3</SystemID>
<id>11</id>
<EntityKey>System.Data.EntityKey</EntityKey>
</NetworkInterfaceArray0>
<NetworkInterfaceArray1>
<IPID isNull="true" />
<Position>0</Position>
<SystemID>3</SystemID>
<id>19</id>
<EntityKey>System.Data.EntityKey</EntityKey>
</NetworkInterfaceArray1>
</systemInterface>
<systemSpecs>
<CPUs>1</CPUs>
<Host><HOST></Host>
<HostName><HostName</HostName>
<MemoryMB>2048</MemoryMB>
<OperatingSystem>Solaris 10</OperatingSystem>
<Stack>Development</Stack>
<Status>Approved</Status>
<Tier>Teir 1 (Front End)</Tier>
<architecture>T-Series</architecture>
<id>3</id>
<EntityKey>System.Data.EntityKey</EntityKey>
</systemSpecs>
<systemStorage attr0="StorageArray" isNull="false">
<StorageArray0>
<Anchor>/def</Anchor>
<SizeMB>2048</SizeMB>
<SystemID>3</SystemID>
<id>11</id>
<EntityKey>System.Data.EntityKey</EntityKey>
</StorageArray0>
</systemStorage>
</virtualServer>
</MethodParameters>
</getServerById>
Reponse from debug:
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body>
<getServerByIdResponse xmlns="http://tempuri.org/">
<getServerByIdResult xmlns:a="http://schemas.datacontract.org/2004/07/DCSP.DataClasses" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<a:systemInterface>
<a:NetworkInterface xmlns:z="http://schemas.microsoft.com/2003/10/Serialization/" z:Id="i1">
<EntityKey xmlns="http://schemas.datacontract.org/2004/07/System.Data.Objects.DataClasses" xmlns:b="http://schemas.datacontract.org/2004/07/System.Data" z:Id="i2">
<b:EntityContainerName>DCSPEntities</b:EntityContainerName>
<b:EntityKeyValues>
<b:EntityKeyMember>
<b:Key>id</b:Key>
<b:Value i:type="c:int" xmlns:c="http://www.w3.org/2001/XMLSchema">11</b:Value>
</b:EntityKeyMember>
</b:EntityKeyValues>
<b:EntitySetName>NetworkInterfaces</b:EntitySetName>
</EntityKey>
<a:IPID>4</a:IPID>
<a:Position>0</a:Position>
<a:SystemID>3</a:SystemID>
<a:id>11</a:id>
</a:NetworkInterface>
<a:NetworkInterface xmlns:z="http://schemas.microsoft.com/2003/10/Serialization/" z:Id="i3">
<EntityKey xmlns="http://schemas.datacontract.org/2004/07/System.Data.Objects.DataClasses" xmlns:b="http://schemas.datacontract.org/2004/07/System.Data" z:Id="i4">
<b:EntityContainerName>DCSPEntities</b:EntityContainerName>
<b:EntityKeyValues>
<b:EntityKeyMember>
<b:Key>id</b:Key>
<b:Value i:type="c:int" xmlns:c="http://www.w3.org/2001/XMLSchema">19</b:Value>
</b:EntityKeyMember>
</b:EntityKeyValues>
<b:EntitySetName>NetworkInterfaces</b:EntitySetName>
</EntityKey>
<a:IPID i:nil="true"/>
<a:Position>0</a:Position>
<a:SystemID>3</a:SystemID>
<a:id>19</a:id>
</a:NetworkInterface>
</a:systemInterface>
<a:systemSpecs xmlns:z="http://schemas.microsoft.com/2003/10/Serialization/" z:Id="i5">
<EntityKey xmlns="http://schemas.datacontract.org/2004/07/System.Data.Objects.DataClasses" xmlns:b="http://schemas.datacontract.org/2004/07/System.Data" z:Id="i6">
<b:EntityContainerName>DCSPEntities</b:EntityContainerName>
<b:EntityKeyValues>
<b:EntityKeyMember>
<b:Key>id</b:Key>
<b:Value i:type="c:int" xmlns:c="http://www.w3.org/2001/XMLSchema">3</b:Value>
</b:EntityKeyMember>
</b:EntityKeyValues>
<b:EntitySetName>Computers</b:EntitySetName>
</EntityKey>
<a:CPUs>1</a:CPUs>
<a:Host>Host</a:Host>
<a:HostName>HostName</a:HostName>
<a:MemoryMB>2048</a:MemoryMB>
<a:OperatingSystem>Solaris 10</a:OperatingSystem>
<a:Stack>Development</a:Stack>
<a:Status>Approved</a:Status>
<a:Tier>Teir 1 (Front End)</a:Tier>
<a:architecture>T-Series</a:architecture>
<a:id>3</a:id>
</a:systemSpecs>
<a:systemStorage>
<a:Storage xmlns:z="http://schemas.microsoft.com/2003/10/Serialization/" z:Id="i7">
<EntityKey xmlns="http://schemas.datacontract.org/2004/07/System.Data.Objects.DataClasses" xmlns:b="http://schemas.datacontract.org/2004/07/System.Data" z:Id="i8">
<b:EntityContainerName>DCSPEntities</b:EntityContainerName>
<b:EntityKeyValues>
<b:EntityKeyMember>
<b:Key>id</b:Key>
<b:Value i:type="c:int" xmlns:c="http://www.w3.org/2001/XMLSchema">11</b:Value>
</b:EntityKeyMember>
</b:EntityKeyValues>
<b:EntitySetName>Storages</b:EntitySetName>
</EntityKey>
<a:Anchor>/def</a:Anchor>
<a:SizeMB>2048</a:SizeMB>
<a:SystemID>3</a:SystemID>
<a:id>11</a:id>
</a:Storage>
</a:systemStorage>
</getServerByIdResult>
</getServerByIdResponse>
</s:Body>
</s:Envelope>

Your question as-is is nigh-impossible to answer, you need to post a sample response as part of your program
See Re: Soap::Lite and Complex Types with WSDL for debug setup to capture data
$soap->transport->add_handler("request_send", \&pp_dump );
$soap->transport->add_handler("response_done", \&pp_dump );
sub pp_dump {
my $content = $_[0]->content('');
$_[0]->content( pp($content) );
print $_[0]->as_string,"\n";
return;
}
sub pp {
use XML::Twig;
open my($fh), '>', \my $str;
no warnings 'newline';
XML::Twig->new(qw! pretty_print record !)->xparse(#_)->print( $fh );
return $str;
}
And see Re^3: SOAP::Lite - Attribute in array for debug setup to access response
my $xml = <<'__XML__';
<?xml version="1.0" encoding="UTF-8"?>
...
__XML__
my $response = SOAP::Custom::XML::Deserializer->deserialize( $xml );

Related

Splatting - Input string was not in a correct format

I can't seem to get my splatting to work in my Invoke-WmiMethod command. I declare the hash table like so:
$HKU = 2147483651
$MyParams = #{
'Class' = 'StdRegProv';
'Name' = 'EnumKey';
'ArgumentList' = "$HKU,''";
'ComputerName' = '';
}
# additional code determining ComputerName... #
$MyParams['ComputerName'] = $MyComputer;
$Vals = Invoke-WmiMethod #MyParams
This line gives me the following error:
Invoke-WmiMethod : Input string was not in a correct format.
At C:\Users\Person\Desktop\tmp.ps1:160 char:20
+ $Vals = Invoke-WmiMethod #MyParams
Do you know what the problem could be?
Try this:
$HKU = 2147483651
$MyParams = #{
'Class' = 'StdRegProv';
'Name' = 'EnumKey';
'ArgumentList' = #($HKU,'');
'ComputerName' = '';
}
$MyParams['ComputerName'] = $MyComputer;
$Vals = Invoke-WmiMethod #MyParams

Cakephp save data and read MAX

I'm trying to save data in CakePHP in this way:
get max entry_id from table translations
(SELECT MAX(entry_id) as res FROM translations) + 1
save data into translations table
$translationData = array('entry_id' => $entry_id, 'language_id' => $key, 'text' => $item);
$translation = new Translation();
$translation->set($translationData);
$translation->save();
again get max entry_id
save next set of data
again get max entry_id
save next set of data
Please have a look at my code:
$this->request->data['Product']['name_tr_id'] = $this->Translation->saveTranslations($this->request->data['Product']['name']);
$this->request->data['Product']['description_tr_id'] = $this->Translation->saveTranslations($this->request->data['Product']['description']);
$this->request->data['Product']['seo_title_tr_id'] = $this->Translation->saveTranslations($this->request->data['Product']['seo_title']);
$this->request->data['Product']['seo_keywords_tr_id'] = $this->Translation->saveTranslations($this->request->data['Product']['seo_keywords']);
$this->request->data['Product']['seo_desc_tr_id'] = $this->Translation->saveTranslations($this->request->data['Product']['seo_desc']);
saveTranslations method:
public function saveTranslations($data) {
$entry_id = $this->getNextFreeId();
foreach($data as $key => $item) {
if($item != "") {
$this->create();
$temp['Translation']['entry_id'] = $entry_id;
$temp['Translation']['language_id'] = $key;
$temp['Translation']['text'] = $item;
$this->save($temp);
}
}
return $entry_id;
}
getNextFreeId method:
public function getNextFreeId() {
$result = $this->query("SELECT MAX(entry_id) as res FROM translations");
return $result[0][0]['res'] + 1;
}
I don't know why entry_id have all the time the same value.
After many hours of searching for solution I finally managed to solve the problem in very easy way - just add false parameter in query method:
$this->query("INSERT INTO translations(entry_id, language_id, text) VALUES($entry_id, $key, '$item')", false);
and
$result = $this->query("SELECT SQL_CACHE MAX(entry_id) as res FROM translations", false);

Cloud Datastore API - php - GqlQuery - Binding args

I'm trying to bind some arguments to my GQL query string.
Everything's fine when I run the query without binding anything:
$result = $DB->query_entities("SELECT * FROM kind WHERE fieldName = 4
LIMIT 1");
But I don't know how to bind some arguments. This is how I'm trying to do so:
function query_entities($query_string, $args=[]){
$gql_query = new Google_Service_Datastore_GqlQuery();
$gql_query->setQueryString($query_string);
$gql_query->setAllowLiteral(true);
if( !empty($args) ){
$binding_args = [];
foreach ($args as $key => $value) {
$binding_value = new Google_Service_Datastore_Value();
$binding_value->setIntegerValue($value);
$arg = new Google_Service_Datastore_GqlQueryArg();
$arg->setName($key);
$arg->setValue($binding_value);
$binding_args[] = $arg;
}
$gql_query->setNameArgs($binding_args);
}
$req = new Google_Service_Datastore_RunQueryRequest();
$req->setGqlQuery($gql_query);
return $this->dataset->runQuery($this->dataset_id, $req, []);
}
$exampleValue = 4;
$result = $DB->query_entities("SELECT * FROM kind WHERE fieldName = :fieldName LIMIT 1", ["fieldName" => $exampleValue]);
Or:
function query_entities($query_string, $args=[]){
$gql_query = new Google_Service_Datastore_GqlQuery();
$gql_query->setQueryString($query_string);
$gql_query->setAllowLiteral(true);
if( !empty($args) ){
$binding_args = [];
foreach ($args as $value) {
$binding_value = new Google_Service_Datastore_Value();
$binding_value->setIntegerValue($value);
$arg = new Google_Service_Datastore_GqlQueryArg();
$arg->setValue($binding_value);
$binding_args[] = $arg;
}
$gql_query->setNumberArgs($binding_args);
}
$req = new Google_Service_Datastore_RunQueryRequest();
$req->setGqlQuery($gql_query);
return $this->dataset->runQuery($this->dataset_id, $req, []);
}
$exampleValue = 4;
$result = $DB->query_entities("SELECT * FROM kind WHERE fieldName = :1 LIMIT 1", [$exampleValue]);
This is what I get:
'Error calling POST https://www.googleapis.com/datastore/v1beta2/datasets/age-of-deployment/runQuery: (400) Lexical error at line 1, column 52. Encountered: ":" (58), after : ""' in ...
Cloud Datastore GQL and Python GQL (App Engine) handle argument binding slightly differently.
In this case, you need to use a # instead of a :, for instance:
SELECT * FROM kind WHERE fieldName = #fieldName LIMIT 1
or
SELECT * FROM kind WHERE fieldName = #1 LIMIT 1
Here's the reference documentation for argument binding in Cloud Datastore GQL.

Backup an entire website and database using PHP

I've been at this for a bit now and this is the closest I've gotten to backing up an entire site and database with PHP. The issue is I can't figure out why I continue to receive errors on lines 145 and 154.
Error:Notice: Undefined variable: arr_zip in C:\xampp\htdocs\wordpress\backup.php on line 145
Warning: Invalid argument supplied for foreach() in C:\xampp\htdocs\wordpress\backup.php on line 145
Notice: Undefined variable: delete_zip in C:\xampp\htdocs\wordpress\backup.php on line 154
<?php
ini_set ("max_execution_time", 0);
$dir = "site-backup-stark";
if(!(file_exists($dir)))
{
mkdir($dir, 0777);
}
$host = "localhost"; //host name
$username = "wordpress_user"; //username
$password = "pasword99"; // your password
$dbname = "wordpress_db"; // database name
$zip = new ZipArchive();
backup_tables($host, $username, $password, $dbname);
/* backup the db OR just a table */
function backup_tables($host,$user,$pass,$name,$tables = '*')
{
$con = mysql_connect($host,$user,$pass);
mysql_select_db($name,$con);
//get all of the tables
if($tables == '*')
{
$tables = array();
$result = mysql_query('SHOW TABLES');
while($row = mysql_fetch_row($result))
{
$tables[] = $row[0];
}
}
else
{
$tables = is_array($tables) ? $tables : explode(',',$tables);
}
$return = "";
//cycle through
foreach($tables as $table)
{
$result = mysql_query('SELECT * FROM '.$table);
$num_fields = mysql_num_fields($result);
$return.= 'DROP TABLE '.$table.';';
$row2 = mysql_fetch_row(mysql_query('SHOW CREATE TABLE '.$table));
$return.= "nn".$row2[1].";nn";
while($row = mysql_fetch_row($result))
{
$return.= 'INSERT INTO '.$table.' VALUES(';
for($j=0; $j<$num_fields; $j++)
{
$row[$j] = addslashes($row[$j]);
$row[$j] = preg_replace("#n#","n",$row[$j]);
if (isset($row[$j]))
{
$return.= '"'.$row[$j].'"' ;
}
else
{
$return.= '""';
}
if ($j<($num_fields-1)) { $return.= ','; }
}
$return.= ");n";
}
$return.="nnn";
}
//save file
$handle = fopen('db-backup-'.time().'-'.(md5(implode(',',$tables))).'.sql','w+');
fwrite($handle,$return);
fclose($handle);
}
if (glob("*.sql") != false)
{
$filecount = count(glob("*.sql"));
$arr_file = glob("*.sql");
for($j=0;$j<$filecount;$j++)
{
$res = $zip->open($arr_file[$j].".zip", ZipArchive::CREATE);
if ($res === TRUE)
{
$zip->addFile($arr_file[$j]);
$zip->close();
unlink($arr_file[$j]);
}
}
}
//get the current folder name-start
$path = dirname($_SERVER['PHP_SELF']);
$position = strrpos($path,'/') + 1;
$folder_name = substr($path,$position);
//get the current folder name-end
$zipname = date('Y/m/d');
$str = "stark-".$zipname.".zip";
$str = str_replace("/", "-", $str);
// open archive
if ($zip->open($str, ZIPARCHIVE::CREATE) !== TRUE)
{
die ("Could not open archive");
}
// initialize an iterator
// pass it the directory to be processed
$iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator("../$folder_name/"));
// iterate over the directory
// add each file found to the archive
foreach ($iterator as $key=>$value)
{
if( strstr(realpath($key), "stark") == FALSE)
{
$zip->addFile(realpath($key), $key) or die ("ERROR: Could not add file: $key");
}
}
// close and save archive
$zip->close();
echo "Archive created successfully.";
if(glob("*.sql.zip") != false)
{
$filecount = count(glob("*.sql.zip"));
$arr_file = glob("*.sql.zip");
for($j=0;$j<$filecount;$j++)
{
unlink($arr_file[$j]);
}
}
//get the array of zip files
if(glob("*.zip") != false)
{
$arr_zip = glob("*.zip");
}
//copy the backup zip file to site-backup-stark folder
foreach ($arr_zip as $key => $value) //error here
{
if (strstr($value, "stark"))
{
$delete_zip[] = $value;
copy("$value", "$dir/$value");
}
}
for ($i=0; $i < count($delete_zip); $i++) //error here
{
unlink($delete_zip[$i]);
}
?>
In this block of code:
//get the array of zip files
if(glob("*.zip") != false)
{
$arr_zip = glob("*.zip");
}
//copy the backup zip file to site-backup-stark folder
foreach ($arr_zip as $key => $value) //error here
If your call to glob("*.zip") returns a 'falsey' value your variable $arr_zip won't be initialised and you'll get an error in the foreach that follows it. Check for false explicitly with
if(glob("*.zip") !== false)
If this continues to fail you need to investigate why glob() is failing. I don't have a suggestion for that.
Later, you haven't initialised $delete_zip at all, somewhere you need
$delete_zip = array();

Drupal 7 db_query

The perfect little module for what I am looking to do was made for drupal 6 but to my dismay it doesn't work on drupal 7. I've have learned that drupal 7 has a new api for the database. I have tried to get it to work but I am admittedly out of my league here. I am hoping some one could give me a little guidance. Specifically with the db_query.
function webform_image_validation_webform_validation_validate($validator_name, $items,
$components, $rule) {
$errors = array();
if ($items) {
switch ($validator_name) {
case 'max_image_size':
$dimensions = explode('x', $rule['data']);
foreach ($items as $key => $val) {
if (is_numeric($val['_fid'])) {
$result = db_query("select * from {files} where fid = %d", $val['_fid']);
while ($data = db_fetch_object($result)) {
$thefile = $data;
}
$image_info = image_get_info($thefile->filepath);
if (webform_image_validation_validate_image($image_info, $dimensions[0], $dimensions[1], FALSE) === FALSE) {
$errors[$key] = t('Your image did not match the required width and/or height. (') . $dimensions[0] . t(' x ') . $dimensions[1] . t(')');
}
}
}
This is the error I receive.
Argument 2 passed to db_query() must be an array, string given, called in
/home/designco/public_html/dev/sites/all/modules/webform_image_validation/
webform_image_validation.module on line 69 and defined in
/home/designco/public_html/dev/includes/database/database.inc on line 2310
It appears I need to add an array but I get lost there. Any help would be appreciated. I'm just trying to find out if I'm the right track.
db_query works differently in Drupal7.
$result = db_query("select * from {files} where fid = %d", $val['_fid']);
while ($data = db_fetch_object($result)) {
$thefile = $data;
}
becomes
$results = db_query("select * from {files} where fid = :fid", array(':fid' => $val['_fid']));
foreach($results as $result) {
// Do your thing for each result.
}
Try changing
$result = db_query("select * from {files} where fid = %d", $val['_fid']);
while ($data = db_fetch_object($result)) {
$thefile = $data;
}
to
$query = db_select('files', 'f')
->fields('f')
->condition('fid', $val['_fid']);
$thefile = $query->execute()->fetchObject();
The Drupal 7 database API docs http://drupal.org/node/310069
thanks JurgenR for the answer.
Just to add one more thing: In drupal 6, we use '%s' for strings. In drupal 7, it is same for all.
For example:
$results = db_query("select * from {files}
where filename = :fname", array(':fname' => $filename));
If you want to search for records starting with a pattern then query will be:
$results = db_query("select * from {files}
where filename = :fname", array(':fname' => $filename.'%'));
Hope this is useful.

Resources