magento rest api create method return - magento

I make an rest api module for shiping and order with carrier and tracking code.
The problem is when i cal the method _created() -(Post) it doesn't return any value. I dont know if the function allow returns or not.
This is my create function
protected function _create($orderData)
{
$orderId = $this->getRequest()->getParam('order_id');
if($orderData['incrementId']){
$incrementId = $orderData['incrementId'];
}else{
$cModel = Mage::getModel('sales/resource_order');
$incrementId = $cModel->getIncrementId($orderId);
}
$order = Mage::getModel('sales/order')
->getCollection()
->addAttributeToFilter('state', array('neq' => Mage_Sales_Model_Order::STATE_CANCELED))
->addAttributeToFilter('increment_id', $incrementId)
->getFirstItem();
if ($order->hasData()) {
if($order->canShip()){
$shipment = new Mage_Sales_Model_Order_Shipment_Api();
$shipmentId = $shipment->create($incrementId);
$trackid = $shipment->addTrack($shipmentId, 'custom', 'ups', '#111111' );
return $shipmentId;
}else{
$this->_critical(self::RESOURCE_NOT_FOUND);
}
}else{
$this->_critical(self::RESOURCE_NOT_FOUND);
}
//return null;
}
The api call:
$resourceUrl = "$apiUrl/shipping/order/1?type=rest";
$oauthClient->fetch($resourceUrl, json_encode($orderData), 'POST', $headers);
print_r($oauthClient->getLastResponse());
I dont know why the response comes empty, even if i errase all the content of the function and just return a value, its comes empty.
Any idea for it?

The answer R.S said is for SOAP instead of REST. You definition is correct.
The return of create is a URL which will appear in http header "location". It is not a valid way to show response for _create event. If you want to response something, you should use _multicreate
if you want to add response data in _multicreate you should use
$this->getResponse ()->addMessage ( "", 0, array (
'id' => $quote->getId ()
), Mage_Api2_Model_Response::MESSAGE_TYPE_SUCCESS );
And you should retrieve the URL in location to receive the correct things.
Use this code to get URL correctly.
$this->_getLocation ( $quote )
Another tricky is you can set the header to make it force redirect
$this->getResponse ()->setRawHeader ( '"Content-Type" = "application/json"' );
However, at this time, only if the magento install in the root of your domain, or the url will be wrong.
Hence you can use some code not good but make things work.
The final code is
$this->getResponse ()->setRawHeader ( '"Content-Type" = "application/json"' );
$base_url = Mage::getBaseUrl ( Mage_Core_Model_Store::URL_TYPE_WEB );
$base_url = substr ( $base_url, 0, strlen ( $base_url ) - 1 );
return $base_url . $this->_getLocation ( $order );

Take a look # Creating a custom API or extending the Core API
Shouldn't your create method be
public function create($customerData){
....

Related

How to pass whole url as params?

I want allow user to scan QR code and go to website. This is search results with params in url address like
http://example.com/qr-code/http://example.org/search/user_id=12&model_id=4&role_id=8
My route is set as
Route::get('qr-code/{data?}/{size?}', 'QrController#qrCode')->name('qr-code');
so i hope my $data will get url:
http://example.org/search/user_id=12&model_id=4&role_id=8
My Controller has
public function qrCode(Request $request, $data = null, $size = 60) {
dd(88);
$data = (empty($data)) ? env('APP_URL') : $data;
return view('qr.code')->with('qr', QrCode::size($size)->generate($data));
}
But i can't even see dd(88) route redirect to main page.
How can i fix that ?
The thing is that Laravel doesn't know that you will provide an entire URL as a parameter. He could interpret everything like that:
http://example.com/qr-code/http:/ /search/user_id=12&model_id=4&role_id=8 . Try encoding the URL diffrently. Your $data will be "http:/" and your size will be 60.
Ok i took i added to helper
function base64url_encode($s) {
return str_replace(array('+', '/'), array('-', '_'), base64_encode($s));
}
function base64url_decode($s) {
return base64_decode(str_replace(array('-', '_'), array('+', '/'), $s));
}
And then i am getting URI from request on view like
Click me
From JS i send params to QrController
public function qrCode(Request $request, $data = null, $type = null, $size = 200) {
$data = (empty($data)) ? env('APP_URL') : $data;
if ($type == 'url') $data = env('APP_URL') . base64url_decode($data);
return view('qr.code')->with('qr', QrCode::size($size)->generate($data));
}
And works fine. Base64 has + or / sometimes so thats why need to replace both - and _ and second is i add base url from env to make whole address.
Thx

CodeIgniter hide post id and only title show in URL

I am working in Codeigniter and I want to hide ID from URL.
my current URL is:
www.localhost/CI/services/1/ac_repair
but need this type of URL in codeigniter:
www.localhost/CI/services/ac_repair
View Page Code:
<?=anchor('services/' . $ser->s_id . '/' . url_title($ser->s_title,'_') ,'View Service');?>
Controller Code:
public function services()
{
$this->load->model('ServicesModel', 'ser_model');
$s_id = $this->uri->segment(2, 0);
if($s_id){
$get_service = $this->ser_model->get_ser($s_id);
return $this->load->view('public/detail', compact('get_service') );
}
else
{
// $services = $this->articles->articles_list( $config['per_page'], $this->uri->segment(3) );
$get_services['result'] = $this->ser_model->all_services_list();
// $this->load->view('public/services', ['services'=>$services]);
$this->load->view('public/services', $get_services);
}
}
Model Code here:
public function get_ser($id)
{
// $q = $this->db
$q = $this->db->select('*')
->from('services')
->where( ['s_id' => $id] )
->get();
if ( $q->num_rows() )
return $q->row();
return false;
}
but need this type of URL in codeigniter:
www.localhost/CI/services/ac_repair
If you want this functionality you have to be able to use your title ac_repair in place of the id. This means the title needs to be marked as unique and therefore not contain any duplicates.
The following pseudo-code should give you an idea:
function services($url_title = null) {
if (!is_null($url_title)) {
// get ser would use title instead of $id
$this->db->where('title', $url_title);
} else {
// all rows
}
}
Other methods would be "hacky" and I cannot think of any off the top of my head that I would consider usable.
Side note: you should never be returning in a view

Laravel 5.6 Mock Guzzle Response

I am trying to mock a guzzle response from a specific api.
My controller code looks like this (amended for brevity):
class SomeClass
{
private $guzzle;
public function __construct(\GuzzleHttp\Client $guzzle) {
$this->guzzle = new $guzzle();
}
public function makeRequest(){
$client = $this->guzzle;
$url = 'http//somerurl';
$options = [];
$response = $client->request('POST', $url, $options);
return $response;
}
}
And the test looks something like this (again edited)...
public function someTest(){
$mock = $this->createMock(\GuzzleHttp\Client::class);
$mock->method('request')->willReturn([
'response' => 'somedata'
]);
$someClass = new $SomeClass($mock);
$response = $someClass->makeRequest();
$body = $response->getBody();
...
}
At this point the test returns "Call to a member function getBody on null";
How can the getBody response of a guzzle call be tested?
Thank you in advance...
One approach to testing with Guzzle is to configure a MockHandler
http://docs.guzzlephp.org/en/stable/testing.html
So instead of mocking the guzzle client, you create one like so:
public function someTest() {
$mock = new MockHandler([
new Response(200, [], 'The body!'),
// Add more responses for each response you need
]);
$handler = HandlerStack::create($mock);
$client = new Client(['handler' => $handler]);
$someClass = new SomeClass($client);
$response = $someClass->makeRequest();
$body = $response->getBody();
$this->assertSame('The body!', $body);
}
The MockHandler requires you to 'queue' responses, meaning you need to know in what order external API calls will be made. I've taken this a step further and wrapped the MockHandler in another handler capable of stuffing a dummy-response into it at the last moment, if one isn't already waiting in the wings. See https://gist.github.com/kmuenkel/d4d473beb7b2297ac2d8cd480089a738
Just use that trait in your test, and call $this->mockGuzzleResponses(); from the test class's setUp() method. At that point, all requests intended to pass through Guzzle will be available for assertions by way of the $guzzleRequestLog property, and all responses can be mocked by calling $this->guzzleHandler->append(RequestInterface); at the beginning of your test.
Just make sure that all implementations of Guzzle in your code are instantiated by way of the app(Client::class) helper and not new Client. Otherwise the binding override won't take effect. That may have been your issue earlier.
Take a look at my composer package https://packagist.org/packages/doppiogancio/mocked-client.
In my opinion, it's a really simple way to mock a Guzzle Client, binding request URLs with responses.
$builder = new HandlerStackBuilder();
// Add a route with a response via callback
$builder->addRoute(
'GET', '/country/IT', static function (ServerRequestInterface $request): Response {
return new Response(200, [], '{"id":"+39","code":"IT","name":"Italy"}');
}
);
// Add a route with a response in a text file
$builder->addRouteWithFile('GET', '/country/IT/json', __DIR__ . '/fixtures/country.json');
// Add a route with a response in a string
$builder->addRouteWithString('GET', '/country/IT', '{"id":"+39","code":"IT","name":"Italy"}');
// Add a route mocking directly the response
$builder->addRouteWithResponse('GET', '/admin/dashboard', new Response(401));
$client = new Client(['handler' => $builder->build()]);
Once you did you will have a fully functional client to use normally
$response = $client->request('GET', '/country/DE/json');
$body = (string) $response->getBody();
$country = json_decode($body, true);
print_r($country);
// will return
Array
(
[id] => +49
[code] => DE
[name] => Germany
)

laravel 3 - (:any) route not working

i am just starting to learn laravel. And found a small sample project from nettuts+ ( url shortner ). it works well but only problem i face is that (:any) route doesn't work.
Here are three routes i have in file.
Route::get('/', function()
{
return View::make('home.index');
});
Route::post('/', function()
{
$url = Input::get('url');
// Validate the url
$v = Url::validate(array('url' => $url));
if ( $v !== true ) {
return Redirect::to('/')->with_errors($v->errors);
}
// If the url is already in the table, return it
$record = Url::where_url($url)->first();
if ( $record ) {
return View::make('home.result')
->with('shortened', $record->shortened);
}
// Otherwise, add a new row, and return the shortened url
$row = Url::create(array(
'url' => $url,
'shortened' => Url::get_unique_short_url()
));
// Create a results view, and present the short url to the user
if ( $row ) {
return View::make('home.result')->with('shortened', $row->shortened);
}
});
Route::get('(:any)', function($shortened)
{
// query the DB for the row with that short url
$row = Url::where_shortened($shortened)->first();
// if not found, redirect to home page
if ( is_null($row) ) return Redirect::to('/');
// Otherwise, fetch the URL, and redirect.
return Redirect::to($row->url);
});
first two routes work fine but third one never gets activated. it only works if i call it with index.php in url. Like /index.php/abc whereas it should work for /abc too. And fyi, i have removed index.php setting from application config file too.
Can you please help ho to fix it?
Change the route declaration from '(:any)'
Route::get('(:any)', function($shortened){ //... });
to ('/(:any)')
Route::get('/(:any)', function($shortened){ //... });

How to configure Module.php in Zend Framework 2 to redirect the user if is not in session (if he is not logged in)?

So, the question is how can I configure Module.php in my module to check if the user is or is not in session?
If he is not I want to redirect him to the log in page.
I don't want the user to has permission to go on other action(controller) if he is not in session(not logged in).
This should be done with event in ZF2 for more details: click here also this code may help you. http://pastebin.com/FFGVCpki
public function init() {
// Attach Event to EventManager
$events = StaticEventManager::getInstance ();
// Add event of authentication before dispatch
$events->attach ( 'Zend\Mvc\Controller\AbstractActionController', 'dispatch', array (
$this,
'authPreDispatch'
), 110 );
}
public function authPreDispatch($event){
$target = $event->getTarget ();
$serviceLocator = $target->getServiceLocator();
// Do what ever you want to check the user's identity
$url = $event->getRouter ()->assemble ( array (
"controller" => "<controller>"
), array (
'name' => '<route name>'
) );
$response = $event->getResponse ();
$response->setHeaders ( $response->getHeaders ()->addHeaderLine ( 'Location', $url ) ));
$response->setStatusCode ( 302 );
$response->sendHeaders ();
exit ();
}
don't use redirect, do setParam() method using 'route' event, see this https://github.com/samsonasik/SanAuthWithDbSaveHandler/commit/e2ae4dfcebb7a952d7b1adaadcf6496c994423b9
Some like:
$e->getRouteMatch()
->setParam('controller', 'Application\Controller\Login')
->setParam('action', 'login');

Resources