How to use Zend Service Amazon? - php

I've been doing a lot of digging around and have ended up with a huge headache and no success. I am trying to use the Zend Amazon Service (within my Codeigniter framework) to fetch information about a book using its ISBN. I initially tried it with Zend 1.12 but I kept getting an error about missing parameter AssociateTag. I am now trying with Zend 2.0 but still getting problems.
This is the code I am using within my controller:
set_include_path(get_include_path() . PATH_SEPARATOR . 'site/libraries');
require_once 'Zend2/Loader/StandardAutoloader.php';
$autoloader = Zend_Loader_Autoloader::getInstance();
$amazon = new Zend_Service_Amazon('[apikey]', 'US', '[secretkey]');
$item = $amazon->itemLookup('B0000A432X');
I get the following error:
Fatal error: Class 'Zend_Loader_Autoloader' not found.
My questions are:
How can I load the correct autoloader?
Where do I include the associate tag in the parameters? There is no mention of it in the outdated zend user guide
Zend 2.0 doesn't even seem to have the amazon service files or even the /service folder. What does this mean?

Note: The demo included with zendservice-amazon doesn't work as is. Requests must include your App ID, Secret Key, and Associate Tag which the demo script doesn't do by default. It took me a while to figure this out, without these, all queries throw an exception saying the HTTP response status was 400. Unfortunately the exception doesn't have the response body which says what parameters were missing.
Here is some code that will get you started with ZF2 and ZendService\Amazon.
To start, let me outline the directory structure of where I will be putting files for this example:
testing
|-Zend
|---Crypt
|---Escaper
|---Http
|---I18n
|---Loader
|----+AutoloaderFactory.php
|----+... more files
|----+StandardAutoloader.php
|-----Exception
|---Stdlib
|---Uri
|---Validator
|-ZendRest
|-ZendService
|---Amazon
|-----Authentication
|-------Exception
|-----Ec2
|-------Exception
|-----Exception
|-----S3
|-------Exception
|-----SimpleDb
|-------Exception
|-----Sqs
|-------Exception
|----+AbstractAmazon.php
|----+...more files
|----+SimilarProduct.php
|-+test.php
The gist is I have created a directory called testing where we will place the ZF2 autoloader as well as the Amazon classes and their dependencies. Under testing is a Zend folder that contains the autoloader (in Loader) and also a ZendService folder where the Amazon service goes.
First, we need to get a copy of the autoloader from ZF2. Part of the reason you were having trouble is because it looks like you are using the ZF1 autoloader which is incompatible with ZF2. To get the Autoloader from ZF2, you can download the latest ZF2 package and copy the Loader directory from ZendFramework-2.0.x/library/Zend/ into the Zend folder we created in the testing directory.
Now that we have the autoloader files, let's grab the Amazon service files. I'll write a detailed answer on how to use Composer to get the latest package, but for now I'll explain how to get it manually. To get the full list of available ZF2 packages, load up the JSON file at http://packages.zendframework.com/packages.json In it find, zendframework/zendservice-amazon, determine the highest version available from the list, and grab the corresponding dist. EDIT As of 11th Jul 2013, this is the latest zendservice-amazon package.
From the library directory in ZendService_Amazon-2.0.2.zip, copy the entire ZendService directory into the testing directory. You now have the ZF2 Amazon service files.
Next, take care of the dependencies. From the ZF2 library, copy the directories, Crypt, Escaper, Http, I18n, Json, Stdlib, Uri, and Validator into the Zend directory inside testing.
You will also need the ZendRest package. Copy the ZendRest folder from library from the ZendRest package to testing/ZendRest.
Now for some code. Create test.php inside the testing folder with the following contents:
<?php
require_once './Zend/Loader/StandardAutoloader.php';
$autoloader = new Zend\Loader\StandardAutoloader(array(
'namespaces' => array(
'Zend' => dirname(__FILE__) . '/Zend',
'ZendRest' => dirname(__FILE__) . '/ZendRest',
'ZendService' => dirname(__FILE__) . '/ZendService',
),
'fallback_autoloader' => true));
$autoloader->register();
$tag = 'prdesign-20'; // replace with your Amazon app ID
$appId = '1JT2V3QNEHDAMKYR5F02'; // replace w/ your access key from https://portal.aws.amazon.com/gp/aws/securityCredentials
$secretKey = 'Qgjeiw39f8UNzjJgeerrgDs1a193du/v7djDAtn/x';
$query = new ZendService\Amazon\Query($appId, 'US', $secretKey);
$query->Category('Books')->Keywords('PHP')->AssociateTag($tag);
$result = $query->search();
foreach($result as $item): ?>
<div class="item">
<?php echo $item->Title ?>
by <?php if (is_array($item->Author)): ?>
<?php echo implode(', ', $item->Author) ?>
<?php else: ?>
<?php echo $item->Author ?>
<?php endif; ?>
</div>
<?php endforeach; ?>
First, we require_once the StandardAutoloader class from ZF2. Once the autoloader is registered, this is the only class you have to manually include.
Next, we create a new autoloader and pass some options. This tells the autoloader where classes in the namespace Zend and ZendService are located. We tell the autoloader they live in the respective folders in our current directory. Change dirname(__FILE__) to the correct path as needed. The fallback_autoloader option tells the autoloader to look for classes of any namespace or vendor in the include_path.
Calling $autoloader->register(); then actually registers the autoloader we set up within PHP. Setting up the autoloader is now finished.
The next 3 lines define some required parameters for the API.
The next 3 lines are straightforward, we now create a new instance of ZendService\Amazon\Query and pass our Amazon app ID and secret key. We then build the query by specifying to search in the Books Category and set the Keywords to be PHP. We also add the required AssociateTag. Finally, we execute the search.
I haven't yet used ZendService\Amazon yet so I can't provide detailed instructions on using the class but the included demo script should get you started with sending basic queries to Amazon and processing the results.
Hope that helps.

i have use Amazon AWS S3 bucket along with Zend Framework. A simple example is photo upload to amazon AWS Bucket.In you application/config/application.ini file
;AWSAccessKeyId= "AccessKey"
;AWSSecretKey= "SecretKey"
;AWSS3BucketName = "zoshare-images"
;AWSS3GetImageUrl = "http://[name].s3.amazonaws.com/[folder]/"
Lets say you want to upload an image to bucket, below is sample code of controller
public function updateAction()
{
if($_FILES["fuPic"]["size"] > 0 || $_FILES["fuPre"]["size"] > 0)
{
$config = Zend_Registry::get('config');
$s3 = new Zend_Service_Amazon_S3($config['AWSAccessKeyId'],$config['AWSSecretKey']);
$bucketName = $config['AWSS3BucketName'];
if($_FILES["fuPic"]["size"] == 0)
unset($_FILES["fuPic"]);
else if($_FILES["fuPre"]["size"] == 0)
unset($_FILES["fuPre"]);
$s3->removeObject($bucketName."/[folder]/".$campaignModel->getCampaignId().'_pic_'.$campaign_olddata->getPicture());
$s3->removeObject($bucketName."/[folder]/".$campaignModel->getCampaignId().'_pre_'.$campaign_olddata->getPreview());
if (isset($_FILES["fuPic"]))
{
$filename = $campaignModel->getCampaignId().'_pic_'.$_FILES["fuPic"]['name'];
$s3->putObject($bucketName."/[folder]/".$filename, file_get_contents($_FILES["fuPic"]["tmp_name"]),
array(Zend_Service_Amazon_S3::S3_ACL_HEADER =>
Zend_Service_Amazon_S3::S3_ACL_PUBLIC_READ));
$data['picture'] = $_FILES["fuPic"]['name'];
}
if (isset($_FILES["fuPre"]))
{
$filename = $campaignModel->getCampaignId().'_pre_'.$_FILES["fuPre"]['name'];
$s3->putObject($bucketName."/[folder]/".$filename, file_get_contents($_FILES["fuPre"]["tmp_name"]),
array(Zend_Service_Amazon_S3::S3_ACL_HEADER =>
Zend_Service_Amazon_S3::S3_ACL_PUBLIC_READ));
$data['preview'] = $_FILES["fuPre"]['name'];
}
}
}
Happy Coding !!!!

Related

Can I use the Blade templating engine outside of Laravel?

i'm want to creating a design pattern and use the "Blade templating engine".
Can I use the Blade templating engine outside of Laravel and use it in my new pattern ?
For the record:
I tested many libraries to run blade outside Laravel (that i don't use) and most are poor hacks of the original library that simply copied and pasted the code and removed some dependencies yet it retains a lot of dependencies of Laravel.
So I created (for a project) an alternative for blade that its free (MIT license, i.e. close source/private code is OK) in a single file and without a single dependency of an external library. You could download the class and start using it, or you could install via composer.
https://github.com/EFTEC/BladeOne
https://packagist.org/packages/eftec/bladeone
It's 100% compatible without the Laravel's own features (extensions).
How it works:
<?php
include "lib/BladeOne/BladeOne.php";
use eftec\bladeone;
$views = __DIR__ . '/views'; // folder where is located the templates
$compiledFolder = __DIR__ . '/compiled';
$blade=new bladeone\BladeOne($views,$compiledFolder);
echo $blade->run("Test.hello", ["name" => "hola mundo"]);
?>
Another alternative is to use twig but I tested it and I don't like it. I like the syntax of Laravel that its close to ASP.NET MVC Razor.
Edit: To this date (July 2018), it's practically the only template system that supports the new features of Blade 5.6 without Laravel. ;-)
You certainly can, there are lots of standalone blade options on packagist, as long as you are comfortable with composer then there should be no issue, this one looks pretty interesting due to having a really high percentage of stars compared to downloads.
Be warned though i have not tried it myself, like you i was looking for a standalone option for my own project and came across it, i will be giving it a real good workout though at sometime in the near future,
Matt Stauffer has created a whole repository showing you how you can use various Illuminate components directly outside of Laravel. I would recommend following his example and looking at his source code.
https://github.com/mattstauffer/Torch
Here is the index.php of using Laravel Views outside of Laravel
https://github.com/mattstauffer/Torch/blob/master/components/view/index.php
You can write a custom wrapper around it so that you can call it like Laravel
use Illuminate\Container\Container;
use Illuminate\Events\Dispatcher;
use Illuminate\Filesystem\Filesystem;
use Illuminate\View\Compilers\BladeCompiler;
use Illuminate\View\Engines\CompilerEngine;
use Illuminate\View\Engines\EngineResolver;
use Illuminate\View\Engines\PhpEngine;
use Illuminate\View\Factory;
use Illuminate\View\FileViewFinder;
function view($viewName, $templateData)
{
// Configuration
// Note that you can set several directories where your templates are located
$pathsToTemplates = [__DIR__ . '/templates'];
$pathToCompiledTemplates = __DIR__ . '/compiled';
// Dependencies
$filesystem = new Filesystem;
$eventDispatcher = new Dispatcher(new Container);
// Create View Factory capable of rendering PHP and Blade templates
$viewResolver = new EngineResolver;
$bladeCompiler = new BladeCompiler($filesystem, $pathToCompiledTemplates);
$viewResolver->register('blade', function () use ($bladeCompiler) {
return new CompilerEngine($bladeCompiler);
});
$viewResolver->register('php', function () {
return new PhpEngine;
});
$viewFinder = new FileViewFinder($filesystem, $pathsToTemplates);
$viewFactory = new Factory($viewResolver, $viewFinder, $eventDispatcher);
// Render template
return $viewFactory->make($viewName, $templateData)->render();
}
You can then call this using the following
view('view.name', ['title' => 'Title', 'text' => 'This is text']);
Yes you can use it where ever you like. Just install one of the the many packages available on composer for it.
If you're interested in integrating it with codeigniter I have a blog post here outlining the process.
Following the above steps should make it obvious how to include it into any framework.

Can't setup Highchart

I am trying to use highchart in cakephp and have followed the below tutorial and also the stackoverflow post on the subject.
I still get a highchart not found.
I downloaded highchartPHP and placed all the 4 files in Vendor/HighchartsPHP
In the layout, I add the lines with the actual js files in webroot/js
echo $this->Html->script('jquery-1.9.1.min'); // Include jQuery library
echo $this->Html->script('highcharts'); // Include jQuery library
This is my code
<?php
App::import('Vendor', 'HighchartsPHP/Highchart');
class ChartsController extends AppController
{
public function index() {
$chart = new Highchart(); /////////////////Error: Class 'Highchart' not found
$chart->chart = array(
'renderTo' => 'container', // div ID where to render chart
'type' => 'line'
);
$chart->series[0]->name = 'Tokyo';
$chart->series[0]->data = array(7.0, 6.9, 9.5);
$this->set( compact( 'chart' ) );
}
In view file
<?php $chart->printScripts(); ?>
<script type="text/javascript">
<?php echo $chart->render("chart");?>
</script>
https://coderwall.com/p/c6yasq
Using HighchartsPHP library in CakePHP
I can't find any more instructions about cakePHP setup with highcharts so I am stuck and I get a highchart not found error.
I still have something missing. What has confused me is that highchartPHP doesn't explain how you install it for a MVC version with cakephp.
How to setup highchart so it works in cakephp ?
I got from the download zip button link so it must be v3
https://github.com/ghunti/HighchartsPHP
also Error: Class 'Highchart' not found from the controller as I outlined above
That's what happens when people don't mention version numbers...
...a year later nobody knows what they were talking about anymore. The tutorial and the question are most probably about version 1.x.
https://github.com/ghunti/HighchartsPHP/tree/v1.0
So a quick fix would be to use v1, but I'm not sure if that's a very good idea as it's probably not maintained anymore.
Namespaces and Composer
Look at the source code of version 2.x and 3.x, they are now using namespaces, and so the class cannot be found when not pointing into that namespace properly.
As mentioned on the projects homepage the library should be installed via composer, and with pretty much all those libraries using composer the generated autoloader needs to be used, but this isn't really the place here to explain how to use composer, this is already extensively covered all over the net.
https://getcomposer.org/doc/00-intro.md
Be sure to check out the CakePHP docs on how to use the composer autoloader with CakePHP too:
[...]
If you’re installing any other libraries with Composer, you’ll need to setup the autoloader, and work around an issue in Composer’s autoloader. In your Config/bootstrap.php file add the following:
// Load Composer autoload.
require APP . 'Vendor/autoload.php';
// Remove and re-prepend CakePHP's autoloader as Composer thinks it is the
// most important.
// See: http://goo.gl/kKVJO7
spl_autoload_unregister(array('App', 'load'));
spl_autoload_register(array('App', 'load'), true, true);
http://book.cakephp.org/.../advanced-installation.html#installing-cakephp-with-composer

Stripe Payments in PHP With Namespaces

I built a PHP application that uses namespaces and PSR-0 autoloading. In trying to implement the Stripe library, I've found that it can't seem to load the classes because they aren't namespaced. Is there a way to not autoload if I have manually included the files?
// Get Stripe Library
require_once(App\App::$APP_PATH . "/Extensions/Stripe.php");
// Set Key
Stripe::setApiKey($stripe['secret_key']);
Setting the key in the example fails with a fatal error because it thinks a Stripe class exists in my namespace of the current file.
I found that if I add a use Stripe; line below my namespace declaration, it will work, but then fails on the next class in the Stripe library.
Am I really going to have to add a Use Stripe, Stripe_Customer, Stripe_xyz...; line to let it load the files correctly (which there are over 25 files) or is there a better way?
[EDIT]
Until I hear whether there is a better way, I've done this:
// Import Non-Namespaced Stripe Library
use Stripe, Stripe_Account, Stripe_ApiConnectionError, Stripe_ApiError, Stripe_ApiRequestor, Stripe_ApiResource, Stripe_AuthenticationError;
use Stripe_Card, Stripe_CardError, Stripe_Charge, Stripe_Coupon, Stripe_Customer, Stripe_Error, Stripe_Event, Stripe_InvalidRequestError;
use Stripe_Invoice, Stripe_InvoiceItem, Stripe_List, Stripe_Object, Stripe_Plan, Stripe_Recipient, Stripe_SingletonApiResource;
use Stripe_Stripe, Stripe_Token, Stripe_Transfer, Stripe_Util;
Using composer is the easiest way (I promise!)
Just install composer and then install stripe. Once you have those installed just browse to your project's folder and run composer install. This will install the needed dependencies and will put composer in a folder called vendor.
Then you simple require the autoload.php file which will load up stripe, without bothering to use a namespace. Here's a full example block that I grabbed from here.
<?php
require_once('vendor/autoload.php');
$stripe = array(
"secret_key" => "sk_test_BQokikJOvBiI2HlWgH4olfQ2",
"publishable_key" => "pk_test_6pRNASCoBOKtIshFeQd4XMUh"
);
\Stripe\Stripe::setApiKey($stripe['secret_key']);
?>
You can use \ to specify that the class name you're specifying is a fully qualified namespace (FQNS), for example:
<?php
use \Stripe, \Stripe_Account;
$stripe = new Stripe();
$stripe_account = new Stripe_Account();
or without use statements:
<?php
$stripe = new \Stripe();
$stripe_account = new \Stripe_Account();

How to install the AWS SDK in Yii

I would like to use the Amazon AWS SDK for PHP in my Yii project, however I get all kinds of include errors (such as include(CFCredentials.php): failed to open stream: No such file or directory ).
I think it may be related to Yii's assumption that class names must match file names...
What can we do??
I've made that:
spl_autoload_unregister(array('YiiBase', 'autoload'));
require_once PATH_TO_AWS_SDK . 'sdk.class.php';
// I write down in PATH_TO_AWS_SDK.'config.inc.php' my CFCredentials
spl_autoload_register(array('YiiBase', 'autoload'));
$amazon_opts = array(
'curlopts' => array(
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_FORBID_REUSE => false,
),
);
$amazon = new AmazonSES();
$response = $amazon->get_send_quota($amazon_opts);
This worked beautifully:
// Include the SDK
Yii::import('application.vendors.aws.*');
spl_autoload_unregister(array('YiiBase', 'autoload'));
require_once 'sdk.class.php';
spl_autoload_register(array('YiiBase', 'autoload'));
// Instantiate the AmazonEC2 class
$ec2 = new AmazonEC2();
In case someone stumbles upon this issue, I've found that if one is using the PHAR file directly (poor decision, I know) and importing via require_once, you cannot call spl_autoload_register to re-add YiiBase autoload until after your SDK call is complete.
At least this was our case when using the StsClient to call assume role with an IAM role.
This is more easier way, You can use Yii S3 Upload extension.
http://www.yiiframework.com/extension/s3upload/

S3 SDK Breaking my site

My problem:
require_once '/includes/aws-sdk-1.5.2/sdk.class.php';
My environment:
I have a pretty standard PHP site that uses __autoload() to grab any classes that I need. However, I now need to include the SDK to send files over to S3, but simply requiring that library seems to throw off the scope of the entire app so that any code that follows is broken.
Example:
// Save to S3
require_once '/var/www/html/system/aws-sdk-1.5.2/sdk.class.php';
$s3 = new AmazonS3();
if( ! $s3->if_bucket_exists(S3_BUCKET) )
throw new Exception('S3 bucket does not exist.');
$response = $s3->create_object(S3_BUCKET, $temp_file['s_unique_name'], array(
'fileUpload' => $_FILES['my_file']['tmp_name'],
'acl' => $s3::ACL_PUBLIC
));
// Save file
$photo = new vehicle_photo();
$photo->i_vehicle = $i_vehicle;
$photo->s_file = $temp_file['s_url'];
$photo->s_label = $_FILES['my_file']['name'];
$photo->save();
So, with the // Save to S3 snippet enabled, the following vehicle_photo class can no longer be found, in addition to all other classes that may be used after this point. If I disable it, everything works.
What's happening here?
Sounds like the autoloading mechanisms are conflicting. You might find this helpful: https://forums.aws.amazon.com/thread.jspa?threadID=85239 . Additionally, spl_autoload_register is better than plain old __autoload - consider migrating your autoloader code to that.

Categories