I have a script which does an Apple push notification to an App. The script is:
$payload['aps'] = array('alert' => 'This is the alert text',
'badge' => 1, 'sound' => 'default',
'article_id'=> '110'
);
$payload = json_encode($payload);
$apnsHost = 'gateway.sandbox.push.apple.com';
$apnsPort = 2195;
$apnsCert = '/var/www/schoolspace/apple_server/mountmercy/MountMercy-dev.pem';
$streamContext = stream_context_create();
stream_context_set_option($streamContext, 'ssl', 'local_cert', $apnsCert);
$deviceToken = "xxxxxxxxxxxxxxxxxxxxxxxxx";
$apns = stream_socket_client('ssl://' . $apnsHost . ':' . $apnsPort, $error, $errorString, 2, STREAM_CLIENT_CONNECT, $streamContext);
$apnsMessage = chr(0) . chr(0) . chr(32) . pack('H*', str_replace(' ', '', $deviceToken)) . chr(0) . chr(strlen($payload)) . $payload;
fwrite($apns, $apnsMessage);
socket_close($apns);
fclose($apns);
I have created the required .pem. When I run this as a standalone script with:
php index.php
everything works and the app receives the notification. There is a warning however:
Warning: socket_close(): supplied resource is not a valid Socket resource
But it still works. However, when I run this in Yii, I get the error:
stream_socket_client() [<a href='function.stream-socket-client'>function.stream-socket-client</a>]: Unable to set private key file `/var/www/schoolspace/apple_server/mountmercy/MountMercy-dev.pem'
I get this error even when setting YII_DEBUG to false. I run this segment of code in the my Yii "Message" model in afterSave(). It's EXACTLY the same as the standalone script. But somehow Yii is preventing it from running. Any ideas?
Since you are receiving the notification that means your pem file might be okay, but
your code doesn't show where you are providing the passphrase. You can try the below code which worked for me.
$badge = 1;
$sound = 'default';
$development = false;//change it to true if in development
$passphrase='passphrase';//pass phrase of the pem file
$payload = array();
$payload['aps'] = array('alert' => $msg_text, 'badge' => intval($badge), 'sound' => $sound);
$payload = json_encode($payload);
$apns_url = NULL;
$apns_cert = NULL;
$apns_port = 2195;
if($development)
{
$apns_url = 'gateway.sandbox.push.apple.com';
$apns_cert = dirname(Yii::app()->request->scriptFile).'/file.pem';
}
else
{
$apns_url = 'gateway.push.apple.com';
$apns_cert = dirname(Yii::app()->request->scriptFile).'/file.pem';
}
$stream_context = stream_context_create();
stream_context_set_option($stream_context, 'ssl', 'local_cert', $apns_cert);
stream_context_set_option($stream_context, 'ssl', 'passphrase', $passphrase);
$apns = stream_socket_client('ssl://' . $apns_url . ':' . $apns_port, $error, $error_string, 2, STREAM_CLIENT_CONNECT, $stream_context);
$device_tokens2= "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
$apns_message = chr(0) . chr(0) . chr(32) . pack('H*', $device_tokens2 ) . chr(0) . chr(strlen($payload)) . $payload;
$msg=fwrite($apns, $apns_message);
#socket_close($apns);
#fclose($apns);
Related
I use the bellow function to resize images after upload to show on my post.
but it works just for images larger than 500px 300px. when I upload image smaller than this size, my website images row breaks down.
use yii\imagine\Image;
public function upload() {
$this->pictureFile->saveAs('../files/upload/' . $this->pictureFile->baseName . '.' . $this->pictureFile->extension);
Image::thumbnail('../files/upload/' . $this->pictureFile, 500, 300)
->save('../files/upload/thumbnail-500x300/' . $this->pictureFile->baseName . '.' . $this->pictureFile->extension,
['quality' => 70]);
unlink('../files/upload/' . $this->pictureFile->baseName . '.' . $this->pictureFile->extension);
}
Instead of Image::thumbnail, try the following
$imagine = Image::getImagine();
$image = $imagine->open('../files/upload/' . $this->pictureFile);
$image->resize(new Box(500, 300))->save('../files/upload/thumbnail-500x300/' . $this->pictureFile->baseName . '.' . $this->pictureFile->extension, ['quality' => 70]);
Haven't tested it but since yii's Image is just a wrapper over Imagine library, this should work with minor changes (if at all needed).
And yes, you need to use Imagine\Image\Box; in your file before using the code above.
Use resize method as below
use yii\imagine\Image;
use Imagine\Image\Box;
public function upload() {
$this->pictureFile->saveAs('../files/upload/' . $this->pictureFile->baseName . '.' . $this->pictureFile->extension);
Image::thumbnail('../files/upload/' . $this->pictureFile, 500, 300)
->resize(new Box(500,300))
->save('../files/upload/thumbnail-500x300/' . $this->pictureFile->baseName . '.' . $this->pictureFile->extension,
['quality' => 70]);
unlink('../files/upload/' . $this->pictureFile->baseName . '.' . $this->pictureFile->extension);
}
Yii::setAlias('newsfolder', dirname(dirname(__DIR__)) . '/frontend/web/extraimages/');
$model->img = UploadedFile::getInstance($model,'img');
if (!empty($model->img)){
$model->img->saveAs( Yii::getAlias('#newsfolder/').$filename.'.'.$model->img->extension );
$model->img = $filename.'.'.$model->img->extension;
$imagine = Image::getImagine();
$image = $imagine->open(Yii::getAlias('#newsfolder/'.$model->img));
$image->resize(new Box(500, 300))->save(Yii::getAlias('#newsfolder/'.$model->img, ['quality' => 70]));
}
$imagine = Image::getImagine();
$imagine = $imagine->open($openPath);
$sizes = getimagesize ( $openPath );
/*
[0] => 604
[1] => 244
[2] => 3
[3] => width="604" height="244"
[bits] => 8
[mime] => image/png
) */
$width = 200;
$height = round($sizes[1]*$width/$sizes[0]);
$imagine = $imagine->resize(new Box($width, $height))->save($savePath, ['quality' => 60]);
I am building my own extension.
I have found this page about adding Flexform to the Extension
https://gist.github.com/alrnz/c0f00b196d378f5b9150
And in my ext_tables.php i have this:
\TYPO3\CMS\Extbase\Utility\ExtensionUtility::registerPlugin(
$_EXTKEY,
'Xlsxtotables',
'XLSX to tables'
);
// Include flex forms
$pluginSignature = str_replace('_', '', $_EXTKEY) . '_' . 'xlsxtotables'; // from registerPlugin(...)
$TCA['tt_content']['types']['list']['subtypes_addlist'] [$pluginSignature] = 'pi_flexform';
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addPiFlexFormValue(
$pluginSignature,
'FILE:EXT:' . $_EXTKEY . '/Configuration/FlexForms/flexform_xlsxtotables.xml'
);
I know that the XML-file is in the right place, but I do not get anyting from it in TYPO3 backend.
Any suggestions?
Try replace
$pluginSignature = str_replace('_', '', $_EXTKEY) . '_' . 'xlsxtotables';
by
$extensionName = strtolower(\TYPO3\CMS\Core\Utility\GeneralUtility::underscoredToUpperCamelCase($_EXTKEY));
$pluginSignature = $extensionName.'_'.'xlsxtotables';
And dont forget to empty your general cache before you see a change with your flexform.
You can try below code in ext_tables.php file
$pluginName = 'Pi1'; // Give Your Plugin Nmae
$pluginSignature = preg_replace('/[^a-z0-9]/', '', strtolower($_EXTKEY)) . '_' . strtolower($pluginName);
// FlexForm configuration
$TCA['tt_content']['types']['list']['subtypes_addlist'][$pluginSignature] = 'pi_flexform';
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addPiFlexFormValue(
$pluginSignature,
'FILE:EXT:' . $_EXTKEY . '/Configuration/FlexForms/flexformname.xml'
);
For Adding Flexforms in One or More Front-end plugins you can use Below code in ext_tables.php
$extensionName = \TYPO3\CMS\Core\Utility\GeneralUtility::underscoredToUpperCamelCase($_EXTKEY);
$frontendpluginName = 'xxx'; //Your Front-end Plugin Name
$pluginSignature = strtolower($extensionName) . '_'.strtolower($frontendpluginName);
$GLOBALS['TCA']['tt_content']['types']['list']['subtypes_addlist'][$pluginSignature] = 'pi_flexform';
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addPiFlexFormValue($pluginSignature, 'FILE:EXT:' . $_EXTKEY . '/Configuration/FlexForms/xyz.xml');
I have a PHP script that adds a new 'A' record to a Cloudflare zone, however, by default these new 'A' records are set as non-active by Cloudflare and now days you can not set them as active when creating them.
So, to edit the new record to set it as active, you need the 'A' records 'rec_id'. In this case action 'rec_load_all' can't be used as there are too many zone 'A' records and I don't think you can filter the request (could be wrong & would be good to be wrong). The zone needs to be filtered.
I have tried the following 'dns_get_rec_one' but it just returns 'NULL' with no error message:
function returnId(){
$request = array();
$request['a'] = 'dns_get_rec_one';
$request['tkn'] = $this->tkn;
$request['email'] = $this->apiEmail;
$request['z'] = 'domain.com';
$request['name'] = 'sub.domain.com';
$response = #json_decode(file_get_contents('https://www.cloudflare.com/api_json.html?' . http_build_query($request)), true);
}
Any ideas as I have little experience with API interactions?
Thanks
Ok, I have worked this out with some help.
When you make the CURL 'rec_new' call to Cloudflare the response includes the 'rec_id' for the new "A" record. This can then be used as the 'id' in the next CURL 'rec_edit' call to edit the record as being active.
The guys at Cloudflare support answer within 24hrs as well and are helpful.
Snippets from class bellow:
private function newSub(){
$fields = array(
'a' => 'rec_new',
'tkn' => $this->tkn,
'email' => $this->apiEmail,
'z' => $this->domain,
'type' => 'A',
'name' => $this->subName,
'content' => $this->content,
'ttl' => 1
);
//url-ify the data for the POST
foreach($fields as $key=>$value){
$fields_string .= $key.'='.$value.'&';
}
rtrim($fields_string, '&');
//open connection
$ch = curl_init();
//set the url, number of POST vars, POST data
curl_setopt($ch,CURLOPT_URL, 'https://www.cloudflare.com/api_json.html');
curl_setopt($ch,CURLOPT_POST, count($fields));
curl_setopt($ch,CURLOPT_POSTFIELDS, $fields_string);
curl_setopt($ch,CURLOPT_RETURNTRANSFER, true);
//execute post
$response = curl_exec($ch);
//close connection
curl_close($ch);
$response = json_decode($response,true);
if(!$response || $response['result'] != 'success'){
$responseError = $response['msg'];
// ERROR Handling
}else{
// Set rec_id for from the nw A record
$this->rec_id = $response['response']['rec']['obj']['rec_id'];
// Activate
$this->makeActive();
}
}
private function makeActive(){
$request['a'] = 'rec_edit';
$request['tkn'] = $this->tkn;
$request['email'] = $this->apiEmail;
$request['z'] = $this->domain;
$request['id'] = $this->rec_id;
$request['type'] = 'A';
$request['name'] = $this->subName;
$request['content'] = $this->content;
$request['service_mode'] = '1';// Make active
$request['ttl'] = '1';
$response = #json_decode(file_get_contents('https://www.cloudflare.com/api_json.html?' . http_build_query($request)), true);
//var_dump($response); die;
if(!$response || $response['result'] != 'success'){
$responseError = $response['msg'];
// ERROR Handling
}
}
Hope that this helps someone.
I use simplecartjs to make a shopping cart on my website where you can select element and send it to your cart... next step, will be the checkout process, but for business reason, no checkout process will append, and a simple form with name and email and date for order pickup will be ask. Now the order must be send to an email address (at the company) that will fullfill the order.
The question : how to send the content of the cart to an email body or as attachement ?
This Will add the email order, suplimentary fields to the user "Phone and Adress",
Check during the CheckOut the the user is registered if not will redirect to registration.
WILL CLEAR Shopping cart only after succesful email order sent.
Will send 2 e-mail to the shop owner "shop#domain.com" and to the users email so he sees the order
Will need to make a new page for the Thank You part after succesful order is made
simplecartjs: around line 288 is in mine
me.emailCheckout = function() {
itemsString = "";
for( var current in me.items ){
var item = me.items[current];
itemsString += item.name + " " + item.quantity + " " + item.price + "\n";
}
var form = document.createElement("form");
form.style.display = "none";
form.method = "POST";
form.action = "sendjs.php";
form.acceptCharset = "utf-8";
form.appendChild(me.createHiddenElement("jcitems", itemsString));
form.appendChild(me.createHiddenElement("jctotal", me.total));
document.body.appendChild(form);
form.submit();
document.body.removeChild(form);
}
sendjs.php
<?php require( dirname(__FILE__) . '/wp-load.php' );
/* cheking is user is logged in*/
if ( is_user_logged_in() ) {
get_currentuserinfo(); /* getting user details*/
/* sending e-mail to the shop email */
$to = 'shop#domain.com';
$subject = 'New Order';
$jcitems = " Name: " . $current_user->user_lastname .
" \n First Name: " . $current_user->user_firstname .
" \n Email: " . $current_user->user_email .
" \n Phone: " . $current_user->phone .
" \n Adress: " . $current_user->adress ;
$headers = 'From: shop#domain.com' . "\r\n" .
'Reply-To: shop#domain.com' . "\r\n" .
'X-Mailer: PHP/' . phpversion();
mail($to, $subject, $jcitems, $headers);
/* sending e-mail with the order to the users email*/
$to = $current_user->user_email;
$subject = 'Order copy from Domain';
$jcitems = "Thank you for you order. Below you have your ordered products".
" \n ORDER: \n\n " . $_POST['jcitems'] . "Total: " . $_POST['jctotal'] . " USD" .
"\n\n http://www.domain.com \nshop#domain.com";
$headers = 'From: shop#domain.com' . "\r\n" .
'Reply-To: shop#domain.com' . "\r\n" .
'X-Mailer: PHP/' . phpversion();
mail($to, $subject, $jcitems, $headers);
/*Clearing the cart info after succesfull order is made*/
setcookie ("simpleCart", "", time() - 3600);
/*redirecting user to Thank you page from Wordpress*/
Header('Location: http://www.domain.com/thank_you/'); }
else { /*sending user to register*/
header( 'Location: http://www.domain.com/wp-login.php?action=register' ) ; exit; } ?>
You will need Register Plus plugin for wordpress to add the extra 2 fiels to the user "phone and address"
be sure to check
Add Registration Field
Add Profile Field
Required
You should add new checkout method to simplecartjs:
me.emailCheckout = function() {
itemsString = "";
for( var current in me.items ){
var item = me.items[current];
itemsString += item.name + " " + item.quantity + " " + item.price + "\n";
}
var form = document.createElement("form");
form.style.display = "none";
form.method = "POST";
form.action = "sendjs.php";
form.acceptCharset = "utf-8";
form.appendChild(me.createHiddenElement("jcitems", itemsString));
form.appendChild(me.createHiddenElement("jctotal", me.total));
document.body.appendChild(form);
form.submit();
document.body.removeChild(form);
}
This will create new form element and submit cart data to sendjs.php. Enable this checkout method by setting me.checkoutTo = 'Email' in simplecart options.
Now create a new sendjs.php file:
<?php
$to = 'you#example.com';
$subject = 'the subject';
$jcitems = $_POST['jcitems'];
$headers = 'From: webmaster#example.com' . "\r\n" .
'Reply-To: webmaster#example.com' . "\r\n" .
'X-Mailer: PHP/' . phpversion();
mail($to, $subject, $jcitems, $headers);
Header('Location: thankyou.html');
?>
This will send the email message and redirect to thankyou.html page you should also create.
I'm building a plugin, and I want to have a Subtable, so that my users can click on the overview data, and display the data from there.
Following the code that I've been able to glean:
public function getCompanyList($idSite, $period, $date )
{
$dataTable = new Piwik_DataTable();
$query = Piwik_Query("SELECT cl.id, cl.company_name name, sf.id sf_id FROM sitedb.company_lookup cl INNER JOIN sitedb.storefronts sf ON cl.id = sf.company_id");
while ($row = $query->fetch()) {
$piwik_row = new Piwik_DataTable_Row;
$piwik_row->setSubTable( $this->getProductsForCompany($idSite, $period, $date, $row['id']) );
$piwik_row->setColumns( array('id' => $row['id'], 'Company Name' => $row['name']) );
$dataTable->addRow($piwik_row);
}
return $dataTable;
}
public function getProductsForCompany($idSite, $period, $date, $company_id )
{
if (!defined('PIWIK_ENABLE_DISPATCH')) define('PIWIK_ENABLE_DISPATCH', false);
if (!defined('PIWIK_ENABLE_ERROR_HANDLER')) define('PIWIK_ENABLE_ERROR_HANDLER', false);
require_once PIWIK_INCLUDE_PATH . "/index.php";
require_once PIWIK_INCLUDE_PATH . "/core/API/Request.php";
Piwik_FrontController::getInstance()->init();
$request = new Piwik_API_Request('
method=Actions.getActions
&idSite=' . $idSite . '
&date=' . $date . '
&period=' . $period . '
&format=PHP
&filter_column=label
&filter_pattern=product.php
&filter_sort_column=nb_visits
&filter_sort_order=desc
&token_auth=anonymous
');
$result = $request->process();
// contains an array of visits to storefront.php
$result = unserialize($result);
$query = Piwik_Query("SELECT sp.product_id id, sp.name, sp.storefront_id sf_id, cl.company_name FROM sitedb.storefront_products sp INNER JOIN sitedb.storefronts sf ON sp.storefront_id = sf.id INNER JOIN sitedb.company_lookup cl ON sf.company_id = cl.id WHERE cl.id = {$company_id}");
$dataTable = new Piwik_DataTable();
while ($row = $query->fetch()) {
// piwik returns & escaped to & -- make sure that's what you use to search!
$this->array_search_in_level("/product.php?id=" . $row['id'] . "&sf_id=" . $row['sf_id'], $result, 'label', $storefront_array, 1);
if (is_array($storefront_array) && array_key_exists('nb_visits', $storefront_array)) {
$piwik_row = new Piwik_DataTable_Row;
$piwik_row->setColumns( array('id' => $row['id'], 'Product Name' => $row['name'], 'Page Views' => $storefront_array['nb_visits']) );
$dataTable->addRow($piwik_row);
}
}
return $dataTable;
}
However, the subTable never shows up. Am I doing something wrong?
Maybe you need to add the 'expanded=1' parameter to your API request?
http://piwik.org/docs/analytics-api/reference/#toc-optional-api-parameters
If you are looking for example code on how to use the piwik framework to plot custom data in plugins, it looks like they have a bit of doc: Piwik plugins docs