Uncaught Error: Call to undefined method PHPExcel::sheetNameExists() - php

I'm getting this error when I try and generate an excel document anyone know where this error is coming from?
Fatal error: Uncaught Error: Call to undefined method
PHPExcel::sheetNameExists() in
/public_html/docs/PHP/PHPExcel/Worksheet.php:835 Stack
trace: #0
/public_html/docs/PHP/PHPExcel/Worksheet.php(337):
PHPExcel_Worksheet->setTitle('Worksheet', false) #1
/public_html/docs/PHP/PHPExcel.php(108):
PHPExcel_Worksheet->__construct(Object(PHPExcel)) #2
/public_html/docs/SendDocument.php(33):
PHPExcel->__construct() #3 {main} thrown in
/public_html/docs/PHP/PHPExcel/Worksheet.php on line 835
<?php
//Excel Data
$Spo = $_SESSION["spo"];
$Cont = $_SESSION["contractNum"];
$Site = $_SESSION["siteMan"];
$Job = $_SESSION["jtd"];
$ObBrief = $_SESSION["ob_Des"];
$ObAgreed = $_SESSION["ob_Act"];
$ObDate = $_SESSION["date1"];
$GoBrief = $_SESSION["good_Des"];
$GoAgreed = $_SESSION["good_Act"];
$GoDate = $_SESSION["date2"];
$FeBrief = $_SESSION["fe_Des"];
$FeAgreed = $_SESSION["fe_Act"];
$FeDate = $_SESSION["date3"];
$Q1 = '';
$Q2 = '';
$Q3 = '';
$Q4 = '';
$Q5 = '';
$Q6 = '';
$Q7 = '';
$Q8 = '';
$Q9 = '';
$Q10 = '';
$Add = $_SESSION["addCom"];
$Name = $_SESSION["name"];
$Title = $_SESSION["title"];
$Date = $_SESSION["date4"];
Include_once 'PHP/PHPExcel.php';
$objPHPExcel = new PHPExcel();
$activeSheet = $objPHPExcel->getActiveSheet();
$objPHPExcel->getActiveSheet()->setTitle('Senior Managers Site Tour');
$objPHPExcel->getActiveSheet()->getColumnDimension('A')->setWidth(5);
$styleArray = array(
'borders' => array(
'allborders' => array(
'style' => PHPExcel_Style_Border::BORDER_THIN
)
)
);
//Set Up
$activeSheet->setCellValue('E1','Senior Managers Site Tour');
$objPHPExcel->getActiveSheet()->getStyle('A1:N70')->applyFromArray($styleArray);
$objPHPExcel->getActiveSheet()->mergeCells('A1:A70');
$objPHPExcel->getActiveSheet()->mergeCells('N1:N70');
$objPHPExcel->getActiveSheet()->getStyle('B6:M68')->getAlignment()->setVertical(PHPExcel_Style_Alignment::VERTICAL_TOP);
$titleArray = array(
'font' => array(
'bold' => true,
'size' => 32,
));
$styleTitleAlign = array(
'alignment' => array(
'horizontal' => PHPExcel_Style_Alignment::HORIZONTAL_CENTER,
)
);
//Title
$objPHPExcel->getActiveSheet()->mergeCells('B1:D4');
$objPHPExcel->getActiveSheet()->mergeCells('E1:M4');
$objPHPExcel->getActiveSheet()->mergeCells('B5:M5');
$objPHPExcel->getActiveSheet()->getStyle('E1')->applyFromArray($titleArray);
$objPHPExcel->getActiveSheet()->getStyle('E1')->applyFromArray($styleTitleAlign);
//Basic Information
$objPHPExcel->getActiveSheet()->mergeCells('B6:D6');
$objPHPExcel->getActiveSheet()->mergeCells('E6:G6');
$objPHPExcel->getActiveSheet()->mergeCells('H6:J6');
$objPHPExcel->getActiveSheet()->mergeCells('K6:M6');
$objPHPExcel->getActiveSheet()->mergeCells('B7:D7');
$objPHPExcel->getActiveSheet()->mergeCells('E7:M7');
$objPHPExcel->getActiveSheet()->mergeCells('B8:D8');
$objPHPExcel->getActiveSheet()->mergeCells('E8:M8');
$objPHPExcel->getActiveSheet()->mergeCells('B9:M10');
$activeSheet->setCellValue('B6','Site / Project / Object:');
$activeSheet->setCellValue('E6', $Spo);
$activeSheet->setCellValue('H6','Contract Number:');
$activeSheet->setCellValue('K6',$Cont);
$activeSheet->setCellValue('B7','Site Manager:');
$activeSheet->setCellValue('E7',$Site);
$activeSheet->setCellValue('B8','Job / Task Description:');
$activeSheet->setCellValue('E8',$Job);
//Observation
$objPHPExcel->getActiveSheet()->mergeCells('B11:M11');
$objPHPExcel->getActiveSheet()->mergeCells('B12:E12');
$objPHPExcel->getActiveSheet()->mergeCells('F12:I12');
$objPHPExcel->getActiveSheet()->mergeCells('J12:M12');
$objPHPExcel->getActiveSheet()->mergeCells('B13:E17');
$objPHPExcel->getActiveSheet()->mergeCells('F13:I17');
$objPHPExcel->getActiveSheet()->mergeCells('J13:M17');
$objPHPExcel->getActiveSheet()->mergeCells('B18:M19');
$activeSheet->setCellValue('B11','OBSERVATION (areas where improvement can be made).');
$activeSheet->setCellValue('B12','Brief Description:');
$activeSheet->setCellValue('B13',$ObBrief);
$activeSheet->setCellValue('F12','Agreed Action:');
$activeSheet->setCellValue('F13',$ObAgreed);
$activeSheet->setCellValue('J12','Close Date:');
$activeSheet->setCellValue('J13',$ObDate);
$objPHPExcel->getActiveSheet()->getStyle('B11')->getFill()->setFillType(PHPExcel_Style_Fill::FILL_SOLID)->getStartColor()->setRGB('D6D6D6');
//Good Practices
$objPHPExcel->getActiveSheet()->mergeCells('B20:M20');
$objPHPExcel->getActiveSheet()->mergeCells('B21:E21');
$objPHPExcel->getActiveSheet()->mergeCells('F21:I21');
$objPHPExcel->getActiveSheet()->mergeCells('J21:M21');
$objPHPExcel->getActiveSheet()->mergeCells('B22:E26');
$objPHPExcel->getActiveSheet()->mergeCells('F22:I26');
$objPHPExcel->getActiveSheet()->mergeCells('J22:M26');
$objPHPExcel->getActiveSheet()->mergeCells('B27:M28');
$activeSheet->setCellValue('B20','GOOD PRACTICES (Commendable acts and actions, Improvements, Innovations etc).');
$activeSheet->setCellValue('B21','Brief Description:');
$activeSheet->setCellValue('B22',$GoBrief);
$activeSheet->setCellValue('F21','Agreed Action:');
$activeSheet->setCellValue('F22',$GoAgreed);
$activeSheet->setCellValue('J21','Close Date:');
$activeSheet->setCellValue('J22',$GoDate);
$objPHPExcel->getActiveSheet()->getStyle('B20')->getFill()->setFillType(PHPExcel_Style_Fill::FILL_SOLID)->getStartColor()->setRGB('D6D6D6');
//Feedback Given & Received
$objPHPExcel->getActiveSheet()->mergeCells('B29:M29');
$objPHPExcel->getActiveSheet()->mergeCells('B30:E30');
$objPHPExcel->getActiveSheet()->mergeCells('F30:I30');
$objPHPExcel->getActiveSheet()->mergeCells('J30:M30');
$objPHPExcel->getActiveSheet()->mergeCells('B31:E35');
$objPHPExcel->getActiveSheet()->mergeCells('F31:I35');
$objPHPExcel->getActiveSheet()->mergeCells('J31:M35');
$objPHPExcel->getActiveSheet()->mergeCells('B36:M37');
$activeSheet->setCellValue('B29','FEEDBACK GIVEN & RECEIVED');
$activeSheet->setCellValue('B30','Brief Description:');
$activeSheet->setCellValue('B31',$FeBrief);
$activeSheet->setCellValue('F30','Agreed Action:');
$activeSheet->setCellValue('F31',$FeAgreed);
$activeSheet->setCellValue('J30','Close Date:');
$activeSheet->setCellValue('J31',$FeDate);
$objPHPExcel->getActiveSheet()->getStyle('B29')->getFill()->setFillType(PHPExcel_Style_Fill::FILL_SOLID)->getStartColor()->setRGB('D6D6D6');
//General Impression
$objPHPExcel->getActiveSheet()->mergeCells('B38:M38');
$objPHPExcel->getActiveSheet()->mergeCells('B39:G39');
$objPHPExcel->getActiveSheet()->mergeCells('H39:M39');
$objPHPExcel->getActiveSheet()->mergeCells('B40:G40');
$objPHPExcel->getActiveSheet()->mergeCells('H40:M40');
$objPHPExcel->getActiveSheet()->mergeCells('B41:M41');
$objPHPExcel->getActiveSheet()->mergeCells('B42:K42');
$objPHPExcel->getActiveSheet()->mergeCells('L42:M42');
$objPHPExcel->getActiveSheet()->mergeCells('B43:K43');
$objPHPExcel->getActiveSheet()->mergeCells('L43:M43');
$objPHPExcel->getActiveSheet()->mergeCells('B44:K44');
$objPHPExcel->getActiveSheet()->mergeCells('L44:M44');
$objPHPExcel->getActiveSheet()->mergeCells('B45:K45');
$objPHPExcel->getActiveSheet()->mergeCells('L45:M45');
$objPHPExcel->getActiveSheet()->mergeCells('B46:K46');
$objPHPExcel->getActiveSheet()->mergeCells('L46:M46');
$objPHPExcel->getActiveSheet()->mergeCells('B47:M47');
$objPHPExcel->getActiveSheet()->mergeCells('B48:K48');
$objPHPExcel->getActiveSheet()->mergeCells('L48:M48');
$objPHPExcel->getActiveSheet()->mergeCells('B49:K49');
$objPHPExcel->getActiveSheet()->mergeCells('L49:M49');
$objPHPExcel->getActiveSheet()->mergeCells('B50:K50');
$objPHPExcel->getActiveSheet()->mergeCells('L50:M50');
$objPHPExcel->getActiveSheet()->mergeCells('B51:K51');
$objPHPExcel->getActiveSheet()->mergeCells('L51:M51');
$objPHPExcel->getActiveSheet()->mergeCells('B52:K52');
$objPHPExcel->getActiveSheet()->mergeCells('L52:M52');
$objPHPExcel->getActiveSheet()->mergeCells('B53:M54');
$activeSheet->setCellValue('B38','GENERAL IMPRESSION');
$activeSheet->setCellValue('B39','1 = No evidence / poor / no understanding');
$activeSheet->setCellValue('H39','2 = Some evidence / understanding / not consistent');
$activeSheet->setCellValue('B40','3 = Requirements in place / basic unerstanding');
$activeSheet->setCellValue('H40','4 = Detailed understanding / more than minimum standards');
$objPHPExcel->getActiveSheet()->getStyle('B38')->getFill()->setFillType(PHPExcel_Style_Fill::FILL_SOLID)->getStartColor()->setRGB('D6D6D6');
$activeSheet->setCellValue('B41','CULTURE');
$activeSheet->setCellValue('B42','Is the CDP obvious - You Said / We Did Boards; Feedback Stations; Posters?:');
$activeSheet->setCellValue('L42',$Q1);
$activeSheet->setCellValue('B43','Are there any Speak Up Coaches on this site?');
$activeSheet->setCellValue('L43',$Q2);
$activeSheet->setCellValue('B44','Are Focus Leader meetings happening?:');
$activeSheet->setCellValue('L44',$Q3);
$activeSheet->setCellValue('B45','Mention the Mental Tools, do people understand them?:');
$activeSheet->setCellValue('L45',$Q4);
$activeSheet->setCellValue('B46','Ask what "Never Harm" means to the teams:');
$activeSheet->setCellValue('L46',$Q5);
$objPHPExcel->getActiveSheet()->getStyle('B41')->getFill()->setFillType(PHPExcel_Style_Fill::FILL_SOLID)->getStartColor()->setRGB('D6D6D6');
$activeSheet->setCellValue('B47','SYSTEM');
$activeSheet->setCellValue('B48','Are first impressions good, site signage, induction etc?:');
$activeSheet->setCellValue('L48',$Q6);
$activeSheet->setCellValue('B49','Is the site tidy, well laid out etc?:');
$activeSheet->setCellValue('L49',$Q7);
$activeSheet->setCellValue('B50','Are morning briefings / daily risk assessment carried out?:');
$activeSheet->setCellValue('L50',$Q8);
$activeSheet->setCellValue('B51','Have all the team been briefed & signed onto the RAMS?:');
$activeSheet->setCellValue('L51',$Q9);
$activeSheet->setCellValue('B52','Ask what they would do if there was a change in the work activity i.e. not in RAMS?:');
$activeSheet->setCellValue('L52',$Q10);
$objPHPExcel->getActiveSheet()->getStyle('B47')->getFill()->setFillType(PHPExcel_Style_Fill::FILL_SOLID)->getStartColor()->setRGB('D6D6D6');
//Comments
$objPHPExcel->getActiveSheet()->mergeCells('B55:M55');
$objPHPExcel->getActiveSheet()->mergeCells('B56:M63');
$objPHPExcel->getActiveSheet()->mergeCells('B64:M65');
$activeSheet->setCellValue('B55','Additional Comments:');
$activeSheet->setCellValue('B56',$Add);
$objPHPExcel->getActiveSheet()->getStyle('B55')->getFill()->setFillType(PHPExcel_Style_Fill::FILL_SOLID)->getStartColor()->setRGB('D6D6D6');
//Completed By
$objPHPExcel->getActiveSheet()->mergeCells('B66:M66');
$objPHPExcel->getActiveSheet()->mergeCells('B67:C67');
$objPHPExcel->getActiveSheet()->mergeCells('D67:G67');
$objPHPExcel->getActiveSheet()->mergeCells('H67:I67');
$objPHPExcel->getActiveSheet()->mergeCells('J67:M67');
$objPHPExcel->getActiveSheet()->mergeCells('B68:C68');
$objPHPExcel->getActiveSheet()->mergeCells('D68:G68');
$objPHPExcel->getActiveSheet()->mergeCells('H68:M68');
$objPHPExcel->getActiveSheet()->mergeCells('B69:M70');
$activeSheet->setCellValue('B66','COMPLETED BY');
$activeSheet->setCellValue('B67','Name:');
$activeSheet->setCellValue('D67',$Name);
$activeSheet->setCellValue('H67','Title:');
$activeSheet->setCellValue('J67',$Title);
$activeSheet->setCellValue('B68','Date:');
$activeSheet->setCellValue('D68',$Date);
$objPHPExcel->getActiveSheet()->getStyle('B66')->getFill()->setFillType(PHPExcel_Style_Fill::FILL_SOLID)->getStartColor()->setRGB('D6D6D6');
$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');
$objWriter->save('Senior Managers Site Tour.xls');
?>

Seems that are using wrong PHPExcel version and you need to re-install the library
See [this answer] for more details.
Investigation
After a code follow-through via PHPExcel repository on GitHub the following observations can be made:
When PHPExcel is instantiated, it's constructor builds worksheets array with one Worksheet.
// Initialise worksheet collection and add one worksheet
$this->workSheetCollection = array();
$this->workSheetCollection[] = new PHPExcel_Worksheet($this);
Notice that Worksheet, when instantiated, gets the PHPExcel instance into its constructor. And this object is assigned to the Worksheets property parent:
public function __construct(PHPExcel $pParent = null, $pTitle = 'Worksheet')
{
// Set parent and title
$this->parent = $pParent;
...
Now, we see that the setTitle method is called from the Worksheet:
$objPHPExcel->getActiveSheet()->setTitle('Senior Managers Site Tour');
Inside setTitle there's the following code:
if ($this->parent) {
// Is there already such sheet name?
if ($this->parent->sheetNameExists($pValue)) {
...
And here the exception is thrown.
We can clearly see the method present in PHPExcel code and we can see that the parent is correctly recognized as a member of this class. So the only conclusion is that wrong version of PHPExcel.php is used. The missing function has only been added in v. 1.8.

Related

PHP-EWS: Set IsRead Flag for a Message

I am writing a php script to read emails from an Exchange Server 2010. Currently, I am able to retrieve all unread emails, but I would like to mark the emails that I have retrieved as read, so I don't retrieve messages I have already retrieved again. I am using php-ews from github. I created a script to do this, but every time it runs I get this error when I call UpdateItem.
PHP Fatal error: SOAP-ERROR: Encoding: object has no 'Path' property
Stack Trace:
#0 ExchangeClient.php(355): SoapClient->__call('UpdateItem', Array)
#1 ExchangeClient.php(355): NTLMSoapClient->UpdateItem(Object(UpdateItemType))
#2 markReadTest.php(20): ExchangeClient->mark_as_read(Object(stdClass))
#3 ExchangeClient.php on line 355
I'm note sure what is causing this error because I think all of my SOAP nesting is correct because I have been referring to Microsoft's EWS SOAP reference for the UpdateItem function. Here is the code for the script that I am using to mark messages as read.
public function mark_as_read($ReadMessage)
{
$request = new EWSType_UpdateItemType();
$request->MessageDisposition = 'SaveOnly';
$request->ConflictResolution = 'AlwaysOverwrite';
$request->ItemChanges = array();
$change = new EWSType_ItemChangeType();
$change->ItemId = new EWSType_ItemIdType();
$change->ItemId->Id = $ReadMessage->ItemId->Id;
$change->ItemId->ChangeKey = $ReadMessage->ItemId->ChangeKey;
$field = new EWSType_SetItemFieldType();
$field->FieldURI = new EWSType_PathToUnindexedFieldType();
$field->FieldURI->FieldURI = 'message:IsRead';
$field->Message = new EWSType_MessageType();
$field->Message->IsRead = True;
$change->Updates->SetItemField[] = $field;
$request->ItemChanges[] = $change;
$response = $this->client->UpdateItem($request);
return $response;
}
After some research I found a comment that provided the solution on a howtoforge post about connecting to EWS through the PHP SOAPclient. The solution was to replace the path element with FieldURI elements in the types.xsd file.
Original XML Tag:
<xs:element ref="t:Path"/>
Replaced By:
<xs:element ref="t:FieldURI"/>
<xs:element ref="t:IndexedFieldURI"/>
<xs:element ref="t:ExtendedFieldURI"/>
This path element occurred 8 times in my version of types.xsd which I got from an Exchange-2013 SP1 server and I replaced all instances of it with the FieldURI elements. After, I did this I was able to mark emails as read without modifying the code I used in my question
Two things that maybe doing it first you should be setting the IsReadSpecified property to true eg
$request = new EWSType_UpdateItemType();
$request->MessageDisposition = 'SaveOnly';
$request->ConflictResolution = 'AlwaysOverwrite';
$request->ItemChanges = array();
$change = new EWSType_ItemChangeType();
$change->ItemId = new EWSType_ItemIdType();
$change->ItemId->Id = $ReadMessage->ItemId->Id;
$change->ItemId->ChangeKey = $ReadMessage->ItemId->ChangeKey;
$field = new EWSType_SetItemFieldType();
$field->FieldURI = new EWSType_PathToUnindexedFieldType();
$field->FieldURI->FieldURI = 'message:IsRead';
$field->Message = new EWSType_MessageType();
$field->Message->IsReadSpecified = true;
$field->Message->IsRead = true;
$change->Updates->SetItemField[] = $field;
$request->ItemChanges[] = $change;
$response = $this->client->UpdateItem($request);
return $response;
Also you might want to look at what the request SOAP is your code is submitting to the server and post that. Its generally a lot clearer from the SOAP what you are doing incorrectly.

why is my rss feed written with php not readable by itunes?

I am trying to sync my rss feed with the podcast section of iTunes. Would somebody be able to help me and tell me why my rss feed is not syncing with itunes? I researched potential issues and didn't seem to find anything that would conflict with my feed. here is the feed
http://www.sportdebaters.com/content/sdrss.php
You haven't used iTunes specific rss tags
take a look at http://www.apple.com/itunes/podcasts/specs.html and http://www.podcast411.com/howto_1.html
This can be a bit hard to get hard, so I've created a small open source library for this.
You can download and learn how to use it here, but let me c/p an example nonetheless:
use iTunesPodcastFeed\Channel;
use iTunesPodcastFeed\FeedGenerator;
use iTunesPodcastFeed\Item;
require __DIR__ . '/vendor/autoload.php';
// SETUP CHANNEL
$title = 'Read2Me Daily Curated Articles';
$link = 'https://read2me.online';
$author = 'NYTimes and Medium';
$email = 'hello#read2me.online';
$image = 'https://d22fip447qchhd.cloudfront.net/api/widget/static/images/default-thumbnail.png';
$explicit = false;
$categories = [
'News',
'Technology',
'Culture',
'Entrepreneurship',
'Productivity'
];
$description = 'Daily curated articles from New York Times and Medium';
$lang = 'en';
$copyright = 'The New York Times Company and The Medium Company';
$ttl = 43200; // 12 hours in seconds
$channel = new Channel(
$title, $link, $author, $email,
$image, $explicit, $categories,
$description, $lang, $copyright, $ttl
);
// SETUP EPISODE
$title = "Trump Says Disclosure of Mueller Questions in Russia Probe Is ‘Disgraceful’";
$fileUrl = 'https://s3.read2me.online/audio/www-nytimes-com-2018-05-01-us-politics-trump-mueller-russia-questions-html-7e9601.mp3';
$duration = '2:18';
$description = 'WASHINGTON — President Trump on Tuesday said it was “disgraceful” that questions the special counsel would like to ask him were publicly disclosed, and he incorrectly noted that there were no questions about collusion. The president also said collusion was a “phony” crime.';
$date = 1525177808;
$filesize = 828387;
$mime = 'audio/mpeg';
$item = new Item(
$title, $fileUrl, $duration,
$description, $date, $filesize, $mime
);
$item2 = clone $item; // just to give you an idea of how it works
// SETUP FEED
$feed = new FeedGenerator($channel, ...[$item, $item2]);
// OUTPUT XML
print $feed->getXml();

Database Query during Dynamic Drupal node creation to get Entity ID

I have a script which grabs the latest image from our surf webcam, it saves a node of type Photos. In that content type i have an entity field which references the swell size (content type swell_data). I can add a static entity id no problem:
// Reference Swell Data ID 176821
$node->field_buoy_ref[$node->language][0]['target_id'] = 176821;
How would I dynamically find the latest node created by the swell_data content type (added hourly using a CRON job) and use that value instead? For your reference this is the current script i am using (thanks to FooNinja)
define('DRUPAL_ROOT', getcwd());
require_once 'includes/bootstrap.inc';
drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);
$bodytext = "This was the view from the Camera at ".date('gA')." on ".date('l F jS Y');
$node = new stdClass(); // Create a new node object
$node->type = "photos"; // Or page, or whatever content type you like
node_object_prepare($node);
$node->title = "Caswell Camera ". date('D M j G:i');
$node->language = LANGUAGE_NONE;
// Author
$node->name = "Gower Live"; // UID of the author of the node; or use $node->name
// Publish Node
$node->status = 1;
//Set Body Text
$node->body[$node->language][0]['value'] = $bodytext;
$node->body[$node->language][0]['summary'] = text_summary($bodytext);
$node->body[$node->language][0]['format'] = 'filtered_html';
//Set Image Location (Caswell)
$node->field_photo_location[$node->language][0]['lat'] = 51.570195982718374;
$node->field_photo_location[$node->language][0]['lng'] = -4.030849980797484;
// Set the Photos date
$node->field_image_date[$node->language][0]['value'] = date("Y-m-d H:i:s");
// From the Webcam
$node->field_webcam_photo[$node->language][0]['value'] = "Caswell";
// Reference Wave Buoy
$node->field_buoy_ref[$node->language][0]['target_id'] = 176821; // I'd this value dynamically pulled from the DB
// Attach Latest Webcam Image
$file_path = drupal_realpath('images/webcams/caswell-webcam.jpg');
$file = (object) array(
'uid' => 1,
'uri' => $file_path,
'filemime' => file_get_mimetype($file_path),
'status' => 1,
);
// You can specify a subdirectory, e.g. public://foo/
$file = file_copy($file, 'public://');
$node->field_user_photo[$node->language][0] = (array) $file;
$path = 'node_created_on' . date('YmdHis');
$node->path = array('alias' => $path);
if($node = node_submit($node)) { // Prepare node for saving
node_save($node);
echo "Node with nid " . $node->nid . " saved!\n";
}
thanks
Lee
I added the following below the Bootstrap Line and bingo.
$result = db_query("SELECT nid, title, created FROM {node} WHERE type = :type AND title =:title", array(
':type' => 'wavebuoy_data',
':title' => "Buoy ". date('D M j gA'),
));
foreach($result as $row) {
$wave_buoy_ref_value = $row->nid;
//print_r($row);
}
Then when building the node, added the following:
// Reference Wave Buoy
$node->field_buoy_ref[$node->language][0]['target_id'] = $wave_buoy_ref_value;
Lee

PHP+SoapClient exceptions and headers? (UPS Rating)

I'm trying to use PHP and SoapClient to utilize the UPS Ratings web service. I found a nice tool called WSDLInterpreter to create a starting point library for creating the service requests, but regardless what I try I keep getting the same (non-descriptive) error:
EXCEPTION=SoapFault::__set_state(array(
'message' => 'An exception has been raised as a result of client data.',
'string' => '',
'code' => 0,
Um ok, what the hell does this mean?
Unlike some of the other web service tools I have implemented, the UPS Soap wants a security block put into the header. I tried doing raw associative array data but I wasn't sure 100% if I was injecting the header part correctly.
Using the WSDLInterpreter, it pulls out a RateService class with a ProcessRate method that excepts it's own (instance) datastructure for the RateRequest and UPSSecurity portions, but all of the above generates that same error.
Here's a sample of the code that I'm using that calls classes defined by the interpreter:
require_once "Shipping/UPS/RateService.php"; // WSDLInterpreter class library
class Query
{
// constants removed for stackoverflow that define (proprietary) security items
private $_upss;
private $_shpr;
// use Interpreter code's RateRequest class to send with ProcessRate
public function soapRateRequest(RateRequest $req, UPSSecurity $upss = null)
{
$res = false;
if (!isset($upss)) {
$upss = $this->__getUPSS();
}
echo "SECURITY:\n" . var_export($upss, 1) . "\n";
$upsrs = new RateService(self::UPS_WSDL);
try {
$res = $upsrs->ProcessRate($req, $upss);
} catch (SoapFault $exception) {
echo 'EXCEPTION=' . var_export($exception, 1) . "\n";
}
return $res;
}
// create a soap data structure to send to web service from shipment
public function getRequestSoap(Shipment $shpmnt)
{
$qs = new RateRequest();
// pickup information
$qs->PickupType->Code = '01';
$qs->Shipment->Shipper = $this->__getAcctInfo();
// Ship To address
$qs->Shipment->ShipTo->Address->AddressLine = $this->__getAddressArray($shpmnt->destAddress->address1, $shpmnt->destAddress->address2);
$qs->Shipment->ShipTo->Address->City = $shpmnt->destAddress->city;
$qs->Shipment->ShipTo->Address->StateProvinceCode = $shpmnt->destAddress->state;
$qs->Shipment->ShipTo->Address->PostalCode = $shpmnt->destAddress->zip;
$qs->Shipment->ShipTo->Address->CountryCode = $shpmnt->destAddress->country;
$qs->Shipment->ShipTo->Name = $shpmnt->destAddress->name;
// Ship From address
$qs->Shipment->ShipFrom->Address->AddressLine = $this->__getAddressArray($shpmnt->origAddress->address1, $shpmnt->origAddress->address2);
$qs->Shipment->ShipFrom->Address->City = $shpmnt->origAddress->city;
$qs->Shipment->ShipFrom->Address->StateProvinceCode = $shpmnt->origAddress->state;
$qs->Shipment->ShipFrom->Address->PostalCode = $shpmnt->origAddress->zip;
$qs->Shipment->ShipFrom->Address->CountryCode = $shpmnt->origAddress->country;
$qs->Shipment->ShipFrom->Name = $shpmnt->origAddress->name;
// Service type
// TODO cycle through available services
$qs->Shipment->Service->Code = "03";
$qs->Shipment->Service->Description = "UPS Ground";
// Package information
$pkg = new PackageType();
$pkg->PackagingType->Code = "02";
$pkg->PackagingType->Description = "Package/customer supplied";
// dimensions
$pkg->Dimensions->UnitOfMeasurement->Code = $shpmnt->dimensions->dimensionsUnit;
$pkg->Dimensions->Length = $shpmnt->dimensions->length;
$pkg->Dimensions->Width = $shpmnt->dimensions->width;
$pkg->Dimensions->Height = $shpmnt->dimensions->height;
$pkg->PackageServiceOptions->DeclaredValue->CurrencyCode = "USD";
$pkg->PackageServiceOptions->DeclaredValue->MonetaryValue = $shpmnt->dimensions->value;
$pkg->PackageServiceOptions->DeclaredValue->CurrencyCode = "USD";
$pkg->PackageWeight->UnitOfMeasurement = $this->__getWeightUnit($shpmnt->dimensions->weightUnit);
$pkg->PackageWeight->Weight = $shpmnt->dimensions->weight;
$qs->Shipment->Package = $pkg;
$qs->CustomerClassification->Code = 123456;
$qs->CustomerClassification->Description = "test_rate_request";
return $qs;
}
// fill out and return a UPSSecurity data structure
private function __getUPSS()
{
if (!isset($this->_upss)) {
$unmt = new UsernameToken();
$unmt->Username = self::UPSS_USERNAME;
$unmt->Password = self::UPSS_PASSWORD;
$sat = new ServiceAccessToken();
$sat->AccessLicenseNumber = self::UPSS_ACCESS_LICENSE_NUMBER;
$upss = new UPSSecurity();
$upss->UsernameToken = $unmt;
$upss->ServiceAccessToken = $sat;
$this->_upss = $upss;
}
return $this->_upss;
}
// get our shipper/account info (some items blanked for stackoverflow)
private function __getAcctInfo()
{
if (!isset($this->_shpr)) {
$shpr = new ShipperType();
$shpr->Address->AddressLine = array(
"CONTACT",
"STREET ADDRESS"
);
$shpr->Address->City = "CITY";
$shpr->Address->StateProvinceCode = "MI";
$shpr->Address->PostalCode = "ZIPCODE";
$shpr->Address->CountryCode = "US";
$shpr = new ShipperType();
$shpr->Name = "COMPANY NAME";
$shpr->ShipperNumber = self::UPS_ACCOUNT_NUMBER;
$shpr->Address = $addr;
$this->_shpr = $shpr;
}
return $this->_shpr;
}
private function __getAddressArray($adr1, $adr2 = null)
{
if (isset($adr2) && $adr2 !== '') {
return array($adr1, $adr2);
} else {
return array($adr1);
}
}
}
It doesn't even seem to be getting to the point of sending anything over the Soap so I am assuming it is dying as a result of something not matching the WSDL info. (keep in mind, I've tried sending just a properly seeded array of key/value details to a manually created SoapClient using the same WSDL file with the same error resulting)
It would just be nice to get an error to let me know what about the 'client data' is a problem. This PHP soap implementation isn't impressing me!
I know this answer is probably way too late, but I'll provide some feedback anyway. In order to make a custom SOAP Header you'll have to override the SoapHeader class.
/*
* Auth Class to extend SOAP Header for WSSE Security
* Usage:
* $header = new upsAuthHeader($user, $password);
* $client = new SoapClient('{...}', array("trace" => 1, "exception" => 0));
* $client->__setSoapHeaders(array($header));
*/
class upsAuthHeader extends SoapHeader
{
...
function __construct($user, $password)
{
// Using SoapVar to set the attributes has proven nearly impossible; no WSDL.
// It might be accomplished with a combined SoapVar and stdClass() approach.
// Security Header - as a combined XSD_ANYXML SoapVar
// This method is much easier to define all of the custom SoapVars with attributes.
$security = '<ns2:Security xmlns:ns2="'.$this->wsse.'">'. // soapenv:mustUnderstand="1"
'<ns2:UsernameToken ns3:Id="UsernameToken-49" xmlns:ns3="'.$this->wsu.'">'.
'<ns2:Username>'.$user.'</ns2:Username>'.
'<ns2:Password Type="'.$this->password_type.'">'.htmlspecialchars($password).'</ns2:Password>'.
'</ns2:UsernameToken>'.
'</ns2:Security>';
$security_sv = new SoapVar($security, XSD_ANYXML);
parent::__construct($this->wsse, 'Security', $security_sv, false);
}
}
Then call the upsAuthHeader() before the soap call.
$client = new SoapClient($this->your_ups_wsdl,
array('trace' => true,
'exceptions' => true,
'soap_version' => SOAP_1_1
)
);
// Auth Header - Security Header
$header = new upsAuthHeader($user, $password);
// Set Header
$client->__setSoapHeaders(array($header));

setting album art of a mp3 with php

I am looking for the best or any way to set the Album Art of mp3s using PHP.
Suggestions?
Album art is a data frame identified as “Attached picture” due ID3v2 specification, and
getID3() now is only one way to write all possible data frames in ID3v2 with pure PHP.
Look at this source:
http://getid3.sourceforge.net/source/write.id3v2.phps
Search for this text in the source:
// 4.14 APIC Attached picture
there's a piece of code responsible for writing album art.
Another way, that seems to be not as slow as pure PHP, is to use some external application, that will be launched by PHP script. If your service designed to work under a high load, binary compiled tool will be a better solution.
A better (faster) way to do this would be through an external application and the PHP exec() function to fun a command. I would recommend eyeD3.
Not sure this is still an issue but:
the amazingly complete getid3() (http://getid3.org) project will solve all your problems. Check out this forum post for more info.
Rather than just share the code for album art update, I an going to post my entire MP3 wrapper class of getID3 here so you can use as you wish
Usage
$mp3 = new Whisppa\Music\MP3($mp3_filepath);
//Get data
$mp3->title
$mp3->artist
$mp3->album
$mp3->genre
//set properties
$mp3->year = '2014';
//change album art
$mp3->set_art(file_get_contents($pathtoimage), 'image/jpeg', 'New Caption');//sets front album art
//save new details
$mp3->save();
Class
<?php
namespace Whisppa\Music;
class MP3
{
protected static $_id3;
protected $file;
protected $id3;
protected $data = null;
protected $info = ['duration'];
protected $tags = ['title', 'artist', 'album', 'year', 'genre', 'comment', 'track', 'attached_picture', 'image'];
protected $readonly_tags = ['attached_picture', 'comment', 'image'];
//'popularimeter' => ['email'=> 'music#whisppa.com', 'rating'=> 1, 'data'=> 0],//rating: 5 = 255, 4 = 196, 3 = 128, 2 = 64,1 = 1 | data: counter
public function __construct($file)
{
$this->file = $file;
$this->id3 = self::id3();
}
public function update_filepath($file)
{
$this->file = $file;
}
public function save()
{
$tagwriter = new \GetId3\Write\Tags;
$tagwriter->filename = $this->file;
$tagwriter->tag_encoding = 'UTF-8';
$tagwriter->tagformats = ['id3v2.3', 'id3v1'];
$tagwriter->overwrite_tags = true;
$tagwriter->remove_other_tags = true;
$tagwriter->tag_data = $this->data;
// write tags
if ($tagwriter->WriteTags())
return true;
else
throw new \Exception(implode(' : ', $tagwriter->errors));
}
public static function id3()
{
if(!self::$_id3)
self::$_id3 = new \GetId3\GetId3Core;
return self::$_id3;
}
public function set_art($data, $mime = 'image/jpeg', $caption = 'Whisppa Music')
{
$this->data['attached_picture'] = [];
$this->data['attached_picture'][0]['data'] = $data;
$this->data['attached_picture'][0]['picturetypeid'] = 0x03; // 'Cover (front)'
$this->data['attached_picture'][0]['description'] = $caption;
$this->data['attached_picture'][0]['mime'] = $mime;
return $this;
}
public function __get($key)
{
if(!in_array($key, $this->tags) && !in_array($key, $this->info) && !isset($this->info[$key]))
throw new \Exception("Unknown property '$key' for class '" . __class__ . "'");
if($this->data === null)
$this->analyze();
if($key == 'image')
return isset($this->data['attached_picture']) ? ['data' => $this->data['attached_picture'][0]['data'], 'mime' => $this->data['attached_picture'][0]['mime']] : null;
else if(isset($this->info[$key]))
return $this->info[$key];
else
return isset($this->data[$key]) ? $this->data[$key][0] : null;
}
public function __set($key, $value)
{
if(!in_array($key, $this->tags))
throw new \Exception("Unknown property '$key' for class '" . __class__ . "'");
if(in_array($key, $this->readonly_tags))
throw new \Exception("Tying to set readonly property '$key' for class '" . __class__ . "'");
if($this->data === null)
$this->analyze();
$this->data[$key] = [$value];
}
protected function analyze()
{
$data = $this->id3->analyze($this->file);
$this->info = [
'duration' => isset($data['playtime_seconds']) ? ceil($data['playtime_seconds']) : 0,
];
$this->data = isset($data['tags']) ? array_intersect_key($data['tags']['id3v2'], array_flip($this->tags)) : [];
$this->data['comment'] = ['http://whisppa.com'];
if(isset($data['id3v2']['APIC']))
$this->data['attached_picture'] = [$data['id3v2']['APIC'][0]];
}
}
Note
There isn't any error handling code yet. Currently, I am just relying on exceptions when I try to run any operations.
Feel free to modify and use as fit. Requires PHP GETID3
Install getId3 using composer composer require james-heinrich/getid3
Then Use this code to update your id3 tags
// Initialize getID3 engine
$getID3 = new getID3;
// Initialize getID3 tag-writing module
$tagwriter = new getid3_writetags;
$tagwriter->filename = 'path/to/file.mp3';
$tagwriter->tagformats = array('id3v2.4');
$tagwriter->overwrite_tags = true;
$tagwriter->remove_other_tags = true;
$tagwriter->tag_encoding = 'UTF-8';
$pictureFile = file_get_contents("path/to/image.jpg");
$TagData = array(
'title' => array('My Title'),
'artist' => array('My Artist'),
'album' => array('This Album'),
'comment' => array('My comment'),
'year' => array(2018),
'attached_picture' => array(
array (
'data'=> $pictureFile,
'picturetypeid'=> 3,
'mime'=> 'image/jpeg',
'description' => 'My Picture'
)
)
);
$tagwriter->tag_data = $TagData;
// write tags
if ($tagwriter->WriteTags()){
return true;
}else{
throw new \Exception(implode(' : ', $tagwriter->errors));
}
You can look into the getID3() project. I can't promise that it can handle images but it does claim to be able to write ID3 tags for MP3s so I think it will be your best bet.
Here is the basic code for adding an image and ID3 data using getID3. (#frostymarvelous' wrapper includes equivalent code, however I think that it is helpful to show the basics.)
<?php
// Initialize getID3 engine
$getID3 = new getID3;
// Initialize getID3 tag-writing module
$tagwriter = new getid3_writetags;
$tagwriter->filename = 'audiofile.mp3';
$tagwriter->tagformats = array('id3v2.3');
$tagwriter->overwrite_tags = true;
$tagwriter->remove_other_tags = true;
$tagwriter->tag_encoding = $TextEncoding;
$pictureFile=file_get_contents("image.jpg");
$TagData = array(
'title' => 'My Title',
'artist' => 'My Artist',
'attached_picture' => array(
array (
'data'=> $pictureFile,
'picturetypeid'=> 3,
'mime'=> 'image/jpeg',
'description' => 'My Picture'
)
)
);
?>
#carrp the $Tagdata code won't work unless each value property is an array e.g.
$TagData = array(
'title' => ['My Title'],
'artist' => ['My Artist'],
'attached_picture' => array(
array (
'data'=> $pictureFile,
'picturetypeid'=> 3,
'mime'=> 'image/jpeg',
'description' => 'My Picture'
)
)
);
Use this inbuilt function of PHP,
<?php
$tag = id3_get_tag( "path/to/example.mp3" );
print_r($tag);
?>
I don't think it's really possible with PHP. I mean, I suppose anything is possible but it may not be a native PHP solution. From the PHP Docs, I think the only items that can be updated are:
Title
Artists
Album
Year
Genre
Comment
Track
Sorry man. Maybe Perl, Python, or Ruby might have some solution.
I'm not sure if you are familiar with Perl (I personally don't like it, but, it's good at things like this...). Here's a script that seems to be able to pull in and edit album art in an MP3: http://www.plunder.com/-download-66279.htm

Categories