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
Related
So I'm working on a reporting application that requires generating Xls files with charts. The charts don't appear to be working though. I've tried just replacing the code below with the example in the PhpSpreadsheet github, but that also doesn't work.
I have the following for inserting the data (and chart) into the worksheet:
$this->spreadsheet->createSheet();
$worksheet = $this->spreadsheet->getActiveSheet();
$worksheet->setTitle($title);
$periodStartArray = array(array('', $periodStartDate, $periodEndDate));
while (!empty($stack)) {
$node = array_pop($stack);
if ($node->getData()['portfolioData'][0] != null) {
if ($node->getData()['portfolioData'][0]->getIncludeInStatusSide()) {
$startValue = (float)$this->getDataPoint($node, 'general', $this->periodStart, 'value');
$startValuePercent = number_format(($startValue / $this->startingTotalValues) * 100, $this->percentDecimals, $decimalPoints, $separators);
$endValue = (float)$this->getDataPoint($node, 'general', $this->periodEnd, 'value');
$endValuePercent = number_format(($endValue / $this->endingTotalValues) * 100, $this->percentDecimals, $decimalPoints, $separators);
$startArray = array($node->getData()['portfolioData'][0]->getNavn(), $startValuePercent, $endValuePercent);
$periodStartArray[] = $startArray;
}
}
}
$maxSize = count($periodStartArray);
$worksheet->fromArray($periodStartArray);
//$title . '!$B$1'
$dataSeriesLabels1 = [
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, $title . '!$B$1', null, 1),
];
// $maxSize - 1 should give the actual number of data points (since the first entry in the array is the
// date row
$dataString = "'" . $title . "'" . '!$A$2:$A$' . $maxSize;
$xAxisTickValues1 = [
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, $dataString, null, $maxSize - 1)
];
$dataString = "'" . $title . "'" . '!$B$2:$B$' . $maxSize;
$dataSeriesValues1 = [
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, $dataString, null, $maxSize - 1)
];
$series = new DataSeries(
DataSeries::TYPE_PIECHART,
null,
range(0, count($dataSeriesValues1) - 1),
$dataSeriesLabels1,
$xAxisTickValues1,
$dataSeriesValues1
);
$layout = new Layout();
$layout->setShowVal(true);
$layout->setShowPercent(false);
$plotArea = new PlotArea($layout, array($series));
$legend = new Legend(Legend::POSITION_RIGHT, null, false);
$title = new Title($title);
$chart1 = new Chart(
'chart1',
$title,
$legend,
$plotArea,
true,
0,
null,
null
);
$chart1->setTopLeftPosition('A10');
$chart1->setBottomRightPosition('P25');
$worksheet->addChart($chart1);
It successfully inserts the data into the spreadsheet, but does not print out any charts. Here is where I'm saving the spreadsheet:
$writer = new \PhpOffice\PhpSpreadsheet\Writer\Xls($this->spreadsheet);
$writer->setIncludeCharts(true);
$writer->save($this->outputFile);
So I'm including the charts, but no charts appear. When I change the format to Xlsx, it seems to at least try to insert the charts but they're corrupt and Excel removes them. It's just simple data. Literally one row of a company name in the A column and two dates of values down the B and C columns. When I manually insert the charts after the excel file gets generated it works no problem.
use this
DataSeries::EMPTY_AS_GAP, // displayBlanksAs
instaea of 0
like in sample file
https://github.com/PHPOffice/PhpSpreadsheet/blob/master/samples/templates/chartSpreadsheet.php
Change the 0 to 'gap' when creating the chart.
$chart1 = new Chart(
'chart1',
$title,
$legend,
$plotArea,
true,
'gap', // use 'gap' instead of 0,
null,
null
);
Below is the issue for PhPSpreadsheet
File containing a chart can not be opened by Excel 2003/2013/2019
I try update a YouTube Video. I use the function at the site https://developers.google.com/youtube/v3/code_samples/php#update_a_video and I try to copy this in my code but if I call listVideos(), I get Google_Service_YouTube_VideoListResponse but I need a Google_Service_YouTube_Video. How can I get it?
My PHP Code:
$youtube = new Google_Service_YouTube($client);
$videoid = "******Video ID********";
$new = "******* TEXT *********";
$videoinfo = $youtube->videos->listVideos('snippet', array('id' => $videoid));
$videoSnippet = $videoinfo[0]['snippet'];
$description = $videoSnippet['description'] . $new;
$videoSnippet['description'] = $description;
$youtube->videos->update("snippet", $videoSnippet);
The Error:
: Uncaught TypeError: Argument 2 passed to
Google_Service_YouTube_Resource_Videos::update() must be an instance of
Google_Service_YouTube_Video, instance of
Google_Service_YouTube_VideoSnippet given, called in
P:\Apache24\htdocs\*********** on line 232 and defined in
P:\Apache24\htdocs\*******\Google Api System\vendor\google\apiclient-
services\src\Google\Service\YouTube\Resource\Videos.php:309
Stack trace:
0 P:\Apache24\htdocs\*********: Google_Service_YouTube_Resource_Videos-
>update('snippet', Object(Google_Service_YouTube_VideoSnippet ))
1 P:\Apache24\htdocs\********\*********\index.php(438):
require('P:\\Apache24\\htd...')
you have to use
$video = $listResponse[0];
$updateResponse = $youtube->videos->update("snippet", $video);
since in the documentation
// Since the request specified a video ID, the response only
// contains one video resource.
$video = $listResponse[0];
$videoSnippet = $video['snippet'];
$tags = $videoSnippet['tags'];
// Preserve any tags already associated with the video. If the video does
// not have any tags, create a new list. Replace the values "tag1" and
// "tag2" with the new tags you want to associate with the video.
if (is_null($tags)) {
$tags = array("tag1", "tag2");
} else {
array_push($tags, "tag1", "tag2");
}
// Set the tags array for the video snippet
$videoSnippet['tags'] = $tags;
// Update the video resource by calling the videos.update() method.
$updateResponse = $youtube->videos->update("snippet", $video);
I am trying to create 2 separate pdf files with different content. I have the following code which creates the 2 files.
$invoice = Invoices::model()->findByPk($_GET['id']);
$invoicedetail = InvoicesDetail::model()->findAll(array("condition"=>"invoiceno=".$invoice->INVOICENO . " && biditems_id is null"));
$client = $invoice->pROJ->oRDERNO->addressesinvoices;
$invoices = Invoices::model()->findAll(array("condition"=>"PROJID=".$invoice->PROJID . " && INVOICENO != ".$invoice->INVOICENO));
/*$this->renderPartial("partialInvoice",
array(
"invoice"=>$invoice,
"client"=>$client,
//"lookupprocesstotalArr"=>$lookupprocesstotalArr,
"adjustments"=>$invoices,
"invoicedetail"=>$invoicedetail[0]
),true);
*/
$html = $this->renderPartial("partialInvoice",
array(
"invoice"=>$invoice,
"client"=>$client,
//"lookupprocesstotalArr"=>$lookupprocesstotalArr,
"adjustments"=>$invoices,
"invoicedetail"=>$invoicedetail[0]),true);
$filename_invoice = 'invoice_'.$invoice->INVOICENO.'.pdf';
Yii::import('application.extensions.pdfable.WkHtmlToPdf');
$pdf = new WkHtmlToPdf(array(
'no-outline', // Make Chrome not complain
'margin-top' => 10,
'margin-right' => 10,
'margin-bottom' => 10,
'margin-left' => 10,
));
$pdf->setOptions(array(
'orientation' => 'portrait'
));
// Add a HTML file, a HTML string or a page from a URL
$pdf->addPage($html);
// Save the PDF
$pdf->saveAs("/tmp/$filename_invoice");
// ... or send to client as file download
/*if(!$pdf->send($filename)){
throw new Exception('Could not create PDF: '.$pdf->getError());
}*/
$globalController = new GlobalController;
//$project = Projects::model()->findAll(array("condition"=>"PROJID=".$_GET['PROJID']));
//$projid = $_GET['PROJID'];
$pdfDetail = new WkHtmlToPdf();
$orientation = "Landscape";
$pdfDetail->setOptions(array('orientation'=>$orientation,
'no-outline', // Make Chrome not complain
'margin-right' => 10,
'margin-bottom' => 5,
'margin-left' => 10,
));
//$this->layout = 'pdf';
//get list of process stages for this project
$lastrun = $globalController->lastRun($invoice->PROJID);
$processstages = ExtHtml::listData($lastrun, 'ID',array('cumulative','ITEM'));
$lookupprocesstotalArr = $globalController->lookupprocesstotal($invoice->PROJID,$processstages);
// get all lines
$connection = Yii::app()->db;
$sql = "SELECT jobs.JOBNO, jobs.NAME, FSP, LSP, SHOTS, KM
FROM hdb.jobs
join detailsseismic on jobs.JOBNO = detailsseismic.JOBNO
where jobs.PROJID = :pid";
$command=$connection->createCommand($sql);
$command->bindValue(":pid",$invoice->PROJID,PDO::PARAM_INT);
$command->execute();
$lines = $command->queryAll();
$dates = array();
foreach ($lines as $arr) {
$sql = "SELECT jobsprocesscomplete.datedone, ITEM_fk
FROM hdb.jobsprocesscomplete
left join lookupprocess on jobsprocesscomplete.lookupprocess_id = lookupprocess.ID
left join biditems on lookupprocess.biditems_id = biditems.ITEMID
where jobno = :jobno";
$command=$connection->createCommand($sql);
$command->bindValue(":jobno",$arr['JOBNO'],PDO::PARAM_INT);
$command->execute();
$dates[$arr['JOBNO']] = $command->queryAll();
}
/*echo $this->renderPartial('pdf_'.$_GET['type'],array(
'lookupprocesstotalArr'=>$lookupprocesstotalArr,
"currency"=>$project[0]->currency0->currency,
"projectpercent"=>$project[0]->PERCENT,
"name"=>$project[0]->PROJECT . " - " . $project[0]->oRDERNO->cONTACTsugar->first_name . " " . $project[0]->oRDERNO->cONTACTsugar->last_name,
"lines"=>$lines,
"dates"=>$dates,
"project"=>$project[0]));
*/
$detail = $this->renderPartial('/lookupprocess/pdf_detail',array(
'lookupprocesstotalArr'=>$lookupprocesstotalArr,
"currency"=>$invoice->pROJ->currency0->currency,
"projectpercent"=>$invoice->pROJ->PERCENT,
"name"=>$invoice->pROJ->PROJECT . " - " . $invoice->pROJ->oRDERNO->cONTACTsugar->first_name . " " . $invoice->pROJ->oRDERNO->cONTACTsugar->last_name,
"lines"=>$lines,
"dates"=>$dates,
"project"=>$invoice->pROJ
),true);
$filename_detail = $invoice->PROJID . "_" . date("ymd-his") . ".pdf";
// Add a HTML file, a HTML string or a page from a URL
$pdfDetail->addPage($detail);
// Save the PDF
$pdfDetail->saveAs("/tmp/$filename_detail");
shell_exec("gs -dBATCH -dNOPAUSE -q -sDEVICE=pdfwrite -sOutputFile=/tmp/$filename_invoice /tmp/$filename_invoice /tmp/$filename_detail");
echo "gs -dBATCH -dNOPAUSE -q -sDEVICE=pdfwrite -sOutputFile=/tmp/$filename_invoice /tmp/$filename_invoice /tmp/$filename_detail";
exit();
/*
// ... or send to client as file download
if(!$pdf->send($filename_invoice)){
throw new Exception('Could not create PDF: '.$pdf->getError());
}
The problem i have is the 1st pdf that gets created is overwritten by the content of the 2nd pdf which makes no sense.
I do not know the class you are using but this code seems suspicios:
-sOutputFile=/tmp/$filename_invoice /tmp/$filename_invoice /tmp/$filename_detail
For me it seems that you convert 2 files into 1 output files, so logically you overwrite it!?
How do I generate a (text only) file in Drupal 7, and attach it to a particular node automatically.
Is there a way to do this with a module, or should I use code to do it in some way (this seems tricky).
First create a file using the drupal file_save_data
$data = 'Your text data'; // Text data to be saved to file.
$filename = 'filename.txt'; // Filename
$file = file_save_data($data,'public://' .$filename);
Now $file will contain the file object that we can attach to the node. Let say you have already created and attached a file field to node type. Lets call it 'field_custom_file'
Then load the node you want to attach then cast the file object to array and attach it to the field.
$node = node_load($nid); // $nid is the id of the node where you want to attach the file.
$node->field_custom_file[LANGUAGE_NONE][] = (array)$file;
node_save($node);
$file = (object) array(
'uid' => 1,
'uri' => $filepath,
'filemime' => file_get_mimetype($filepath),
'status' => 1,
'display' => 1,
);
$file = file_copy($file, 'public://');
$node->field_file['und'][0] = $file;
I have this class content in which i am using s3 and sdb class how can i improve this class structure for using advanced oop concepts.
<?php
Class content{
function getcontent(){
if(!$_GET){
echo "{'success':false, 'error':'No query parameters submitted'}";
return;
}
// create connection
$sdb = new SimpleDB(awsAccessKey, awsSecretKey);
$condition = "";
$status = "";
//$params = json_decode(stripslashes($_POST['hash']));
$params = $_GET;
unset($params['command']);
foreach($params as $key => $value){
$condition .= " " . $key . " = '" . $value . "' and" ;
}
$condition = preg_replace('/and$/', "", $condition);
if($condition!='')
$condition=" and ".$condition;
$query = "select * from ".domain;
if($condition!= " _empty_ = '' "){
$query .= " where time_stamp is not null $condition order by time_stamp asc";
}
//~ echo $query;
$fileHash = '{';
if($files = $sdb->select($domain, $query)){
$status = 'true';
}else{
$status = 'false';
$files= array();
$message = "No records retrieved from SimpleDB ".json_encode($sdb->ErrorCode);
}
$array=array(
'files'=>$files,
'success'=>$status,
'message'=>$message
);
echo (json_encode($array));
}
function getthumb(){
$_url = $_REQUEST['url'];
$url='';
if ( $_url != "" ) {
echo $url = file_get_contents("$_url");
}
return $url;
}
function upload(){
//instantiate the S3 class
$s3 = new S3(awsAccessKey, awsSecretKey);
//instantiate the SimpleDB class
$sdb = new SimpleDB(awsAccessKey, awsSecretKey);
// Set temp directory where files will be written temporarily
$uploaddir = 'uploads/';
// Max file size 100 MB
$maxFileSize = 100 * 1024 * 1024;
$thumb = '';
$status = '';
$imgWidth = '';
$imgHeight = '';
// Get file size from Apache headers
$fileSize = getSize();
// Get MIME type from Apache headers
$fileType = getFileType();
if ($fileSize == 0){
return array(success=>false, error=>"File is empty.");
}
if ($fileSize > $maxFileSize){
return array(success=>false, error=>"File is too large.");
}
// Put data of pathinfo() array into $pathinfo
$pathinfo = pathinfo(getName());
// Get file name - eg: myphoto
$filename = $pathinfo['filename'];
// Get extension - eg: .jpg
$ext = $pathinfo['extension'];
$originalName = $filename.'.'.$ext;
// Generate unique id for the current object
$randName = uniqid();
// Unique file name with extension
$fileTempName = $randName . '.' . $ext;
// Complete temp file name and path
$fullTempName = $uploaddir . $fileTempName;
// Upload the file to temp directory on .net server
save($fullTempName);
// If images, call the function imgThumbs() to generate thumbnails
if(preg_match("/^image/", $fileType)){
$tbnail = $_GET['thumb_size'];
$thumb = imgThumbs($tbnail, $fullTempName, $fileType, bucket, cloudfront);
if($_REQUEST['profile_pic']=='y'){
$crop_url=$thumb;
}
list($imgWidth, $imgHeight) = getimagesize($fullTempName);
}
// If videos, call convertVideo() and return path of converted video. Then call vidThumbs() to generate thumbnails
if(preg_match("/^video/", $fileType)){
$fullTempName = convertVideo($fullTempName, $fileType); // Capture filename with complete path and flv extension
$fileTempName = preg_replace('/^uploads\//', '', $fullTempName);// Remove directory to get only the filename of flv
$fileType = "video/x-flv"; // Assign $fileType
$randName = substr($fileTempName, 0, 13); // Parse and assign the unique id to $randName
$imgWidth = 120; // Hardcoding width of video thumbnail
$imgHeight = 90; // Hardcoding height of video thumbnail
$thumb = vidThumbs($fullTempName, bucket, cloudfront); // Call the video thumbnail func
}
// If audio, call convertAudio() and return path of converted audio.
if(preg_match("/^audio/", $fileType)){
$fullTempName = convertAudio($fullTempName, $fileType); // Capture filename with complete path and mp3 extension
$fileTempName = preg_replace('/^uploads\//', '', $fullTempName);// Remove directory to get only the filename of mp3
$fileType = "audio/mpeg"; // Assign $fileType
$randName = substr($fileTempName, 0, 13); // Parse and assign the unique id to $randName
$imgWidth = $imgHeight = 100; // Hardcoding for positioning the thumbnail for audio
$thumb = 'http://dtzhqpwfdzscm.cloudfront.net/4c7247570bd4b.jpg'; // Hardcoding this url for audio thumbs
}
// Metadata for SimpleDB
$contentObjectType = "upload";
$timeStamp = time();
$url = cloudfront.$fileTempName;
$on_floor = "true";
/*
* An array of (name => (value [, replace])),
* where replace is a boolean of whether to replace the item.
* replace is optional, and defaults to false.
* If value is an array, multiple values are put.
*/
$putAttributesRequest = array(
"contentid" => array("value" => "$randName"), // unique id for EVERY object and link
"content_obj_type" => array("value" => "$contentObjectType"), // whether link or file upload
"file_name" => array("value" => "$fileTempName"), // unique generated filename
"url" => array("value" => "$url"), //file's CDN url
"original_name" => array("value" => "$originalName"), //original name of the file
"file_size" => array("value" => "$fileSize"), //size of file uploaded
"time_stamp" => array("value" => "$timeStamp"), //time
"file_type" => array("value" => "$fileType"), //mime type of uploaded file
"thumb" => array("value" => "$thumb"), //thumbnail link
"width" => array("value" => "$imgWidth"), //width of uploaded image
"height" => array("value" => "$imgHeight"), //height of uploaded image
"on_floor" => array("value" => "$on_floor") //by default all cObj on floor
);
// Get ALL the parameter hash passed
$contentObjHash = getParam();
foreach($contentObjHash as $key => $value){
$putAttributesRequest["$key"] = array("value" => "$value");
}
//check whether a form was submitted
if(isset($fileTempName)){
// Begin object hash here
$objHash = '{';
/* Move the file to S3
*
* #param mixed $fileTempName Location of temp file
* #param string bucket Bucket
* #param string $newFileName Unique generated file name
* #param constant ACL
* #param array() Dont worry about this
* #param string $fileType MIME type of file
* #return boolean
*/
if($_REQUEST['profile_pic']!='y' && !$s3->putObjectFile($fullTempName, bucket, $fileTempName, S3::ACL_PUBLIC_READ, array(), $fileType) ) {
$status = 'false';
$objHash .= "success : ".json_encode($status)."}"; // End object hash here id S3 error
echo $objHash;
return;
}
/**
* Create or update attributes
*
* #param string $domain Domain
* #param string $randName Unique generated file name
* #param array $putAttributesRequest See up for more info
* #return boolean
*/
if($sdb->putAttributes(domain, $randName, $putAttributesRequest)){
$status = 'true';
unlink($fullTempName);
}else{
$status = 'false';
$objHash .= "'SimpleDB_error' : ".json_encode($sdb->ErrorCode).",";
}
foreach($putAttributesRequest as $key => $value){
$objHash .= json_encode($key). " : " . json_encode($value["value"]) .", ";
}
$objHash .= "'success' : ".$status."}"; // End object hash after SimpleDB transaction
echo $objHash;
}
}
}
?>
Using the class by this code :
$content=new content();
switch($command){
case 'getcontent':
$content->getcontent();
break;
case 'thumb':
$content->getthumb();
break;
case 'upload':
$content->upload();
break;
case 'update':
$content->update();
break;
default:
break;
}
-- comment
your class seems to be more like a "service" class (you don't have any property). Then you need just one instance of the class : implement the singleton pattern. If the instance is used quite often or once created, you call almost all methods : create a DB attribute to avoid multiple connections (actually you could do that with a singleton on the application scope). All of that depends on your way of use the class.
-- /comment
for the singleton pattern, read this.
About the DB attribute, it will allow you to connect just once for each instance of the Content Class instead of several local variables in methods.
It could be useful in case of multiple calls of methods that need DB which is not your case for the moment.
Here is an example :
Class content{
private $db=null; // db
public function __construct(){ // CONSTRUCTOR : called with the new operator
// create connection (created once for the instance)
$this->db = new SimpleDB(awsAccessKey, awsSecretKey);
// you can pass the connection strings as parameter
}
public function getcontent(){
// You should not use directly GET here : pass it as parameter
// as the origin of the data may change some day
// in this method, it doesn't where the data come from
// -> encapsulation : the code keeps consistent when environment changes
if(!$_GET){
echo "{'success':false, 'error':'No query parameters submitted'}";
return;
}
...
// query something using the local attribute
if($files = $this->db->select($domain, $query)){