How to add limit option in Magento API call - magento

I am creating web service for my store. I am using magento API to collect product list from store. But it display all the 500 records. And i want it 25 records per page. What to add in API call? Or What filter will be apply for this?
//create soap object
$proxy = new SoapClient('http://localhsot/magento/api/soap/?wsdl');
// create authorized session id using api user name and api key
// $sessionId = $proxy->login('apiUser', 'apiKey');
$sessionId = $proxy->login('test_admin', '12345678');
$filters = array(
);
// Get list of product
$productlist = $proxy->call($sessionId, 'product.list', array($filters));
print_r($productlist );

that didn't work, can you limit it by id like:
$filters = array('id'=>array("gteq"=>1), 'id'=>array("lteq"=>1000));
that way you could add some paging?

I know this is an old question but I struggled with this. I've created my own SOAP API endpoint which does exactly the same as the default catalogProductList function but has an extra param. See the code below:
$collection = Mage::getModel('catalog/product')->getCollection()
->addStoreFilter($this->_getStoreId($store))
->addAttributeToSelect('name');
if($limit) {
$collection->setOrder('updated_at', 'ASC');
$collection->setPageSize($limit);
}
/** #var $apiHelper Mage_Api_Helper_Data */
$apiHelper = Mage::helper('api');
$filters = $apiHelper->parseFilters($filters, $this->_filtersMap);
try {
foreach ($filters as $field => $value) {
$collection->addFieldToFilter($field, $value);
}
} catch (Mage_Core_Exception $e) {
$this->_fault('filters_invalid', $e->getMessage());
}
$result = array();
foreach ($collection as $product) {
$result[] = array(
'product_id' => $product->getId(),
'sku' => $product->getSku(),
'name' => $product->getName(),
'set' => $product->getAttributeSetId(),
'type' => $product->getTypeId(),
'category_ids' => $product->getCategoryIds(),
'website_ids' => $product->getWebsiteIds(),
'updated_at' => $product->getUpdatedAt(),
'created_at' => $product->getCreatedAt()
);
}
return $result;
And from there we keep track of the last updated_at value and use that as a filter to get the next [LIMIT] items. By default updated_at and created_at are not in the response and the list is not orderred by updated_at so I've added this.

I am not sure of this but you could try this, as the API is working with collections and this is the way to limit a collection size
$filters = array(
'setPageSize' => 10
);

Related

Laravel 7 : Why I am Getting Only First Array? I want to Fetch All Category ID data

I am getting a issue while fetching array data in Laravel 7 here is my code
https://i.stack.imgur.com/IZbg6.png
and the result is : https://i.stack.imgur.com/ByKaV.png
It is fetching only one array data. I don't know where i am missing.
If anybody know the error, please help me to solve this issue.
Below is my code ======================================
$cat_id = $category->id;
$location = null;
$sites = \DB::select( 'SELECT id FROM sites WHERE category_id = ?', [ $category->id ]);
$all = [ ];
foreach( $sites as $s ) {
$all[ ] = $s->id;
}
$sites = $all;
$all_cat_id = implode(',', array_map('intval', $sites));
// echo "<pre>";
// print($all_cat_id);
// die();
$sites = Sites::withCount('reviews')->orderBy('reviews_count', 'desc')->where('id', [$all_cat_id])->paginate(10);
return view('browse-category', [ 'activeNav' => 'home',
'reviews' => $reviews,
'sites' => $sites,
'category' => $category,
'all_categories' => $all_categories,
'location' => $location
]);
$sites = Sites::withCount('reviews')->orderBy('reviews_count', 'desc')->whereIn('id', [$all_cat_id])->paginate(10);
You need to use whereIn() instead of where()
whereIn() checks column against array.

laravel DB update get changes column

i want to save log of changes when i update something on the database.
there is elegant way to get the column that will be updated (just if there is change).
i want to save the old column value in log..
for example:
$updateUser = DB::table('users')->where('id','1')->update(array('email' => 'new#email.com', 'name' => 'my new name'));
from this i want to get back the old email was in database (if changed) and the old name (again, only if changed)
thanks!
As others have mentioned, Eloquent is a great way to go if using Laravel. Then you can tap directly into Laravel's events using Observers. I have used a method very similar to what is below. Of course, you would need to set up Models for User and AuditLog.
See more info regarding Observers.
https://laravel.com/docs/5.8/eloquent#observers
In Controller Method
$user = User::find(1);
$user->update([
'email' => 'new#email.com',
'name' => 'my new name'
]);
App/Providers/EventServiceProvider.php
class EventServiceProvider extends ServiceProvider
{
// ...
public function boot()
{
User::observe(UserObserver::class);
}
}
App/Observers/UserObserver.php
class UserObserver
{
/**
* The attributes to exclude from logging.
*
* #var array
*/
protected $except = [
'created_at',
'updated_at'
];
/**
* The attributes to mask.
*
* #var array
*/
protected $masked = [
'password',
];
/**
* Listen for model saved event.
*
* #var array
*/
public function saved($model)
{
// search for changes
foreach ($model->getChanges() as $key => $new_value) {
// get original value
$old_value = $model->getOriginal($key);
// skip type NULL with empty fields
if ($old_value === '' && $new_value === null) {
continue;
}
// attribute not excluded and values are different
if (!in_array($key, $this->except) && $new_value !== $old_value) {
// mask designated fields
if (in_array($key, $this->masked)) {
$old_value = '********';
$new_value = '********';
}
// create audit log
AuditLog::create([
'user_id' => auth()->user()->id,
'model_id' => $model->id,
'model' => (new \ReflectionClass($model))->getShortName(),
'action' => 'update',
'environment' => config('app.env'),
'attribute' => $key,
'old_value' => $old_value,
'new_value' => $new_value,
]);
}
}
}
}
I hope this helps!
EDIT: See comment regarding update.
I will suggest 2 options:
1) to use the Eloquent model on every changes,
and then to use the existing methods like :
model->isDirty()
model->getChanges()
you can implement it on the model life cycle of updating / updated events listeners
more information and example you can see here:
https://laravel.com/docs/5.8/events
https://medium.com/#JinoAntony/10-hidden-laravel-eloquent-features-you-may-not-know-efc8ccc58d9e
https://laravel.com/api/5.3/Illuminate/Database/Eloquent/Model.html
2) if you want to log changes even if you are running regular queries and not only via model life cycle,
you can use MySql Triggers on every table updates and then to check OLD vs NEW and insert directly to the log changes db
more information you can find here:
https://dev.mysql.com/doc/refman/8.0/en/trigger-syntax.html
MySQL Trigger after update only if row has changed
Why not just something like this:
$changeArr = ['email' => 'new#email.com', 'name' => 'my new name'];
$id = 1;
$table = 'users';
foreach($changeArr as $key => $value){
DB::table('updateTable')->insert(['table' => $table, 'id' => $id, 'col' => $key, 'oldVal' => $value]);
}
$updateItem = DB::table($table)->where('id', $id)->update($changeArr);
Check for the changed values and update accordingly, saving the old values to log table if changed
$newData = ['email' => 'new#email.com', 'name' => 'my new name'];
$user = App\User::find(1);
$log = [];
if ($user->email != $newData['email']) {
$log['user_id'] = $user->id;
$log['email'] = $user->email;
$user->email = $newData['email'];
} elseif ($user->name != $newData['name']) {
$log['name'] = $user->name;
$user->name = $newData['name'];
$logged = DB::table('log')->insert($log);
}
$updateUser = $user->save();
//try this. hpe it helps out:
function Update(Request $request, $id)
{
$dbrecord = DB::table('users')->where('id',$id)->first();
$oldemail = $dbrecord->email;
$oldname = $dbrecord->name;
if(($oldemail==$request->input('email'))&&($oldname==$request->input('name')))
{
//do nothing
}
elseif(($oldemail!=$request->input('email'))or($oldname!=$request->input('name')))
{
$updateUser = DB::table('users')->where('id',$id)->update(array('email' => $request->input('email'), 'name' => $request->input('name')));
if($updateUser)
{
DB::table('log')->where('id',$id)->insert(array('email' => $oldemail, 'name' => $oldname));
}
}
}

Method not allowed exception while updating a record

Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpExceptionNomessage
I'm getting this error while trying to update a record in the database. Don't know what's the problem. This question might be a duplicate but I've checked all and couldn't find the answer. Please Help me with this.
Controller Update Method:
public function updateEvent(Request $request, $id=''){
$name = $request->name;
$startdate = date_create($request->start_date);
$start_date = $startdate;
$time = $request->start_time;
$start_time = $time;//date("G:i", strtotime($time));
$endDate = date_create($request->end_date);
$end_date =$endDate;
$time_e = $request->end_time;
$end_time = $time_e;//date("G:i", strtotime($time_e));
$location = $request->location;
$description = $request->description;
$calendar_type = $request->calendar_type;
$timezone = $request->timezone;
if ($request->has('isFullDay')) {
$isFullDay = 1;
}else{
$isFullDay = 0;
}
DB::table('events')->where('id', $id)->update(
array(
'name' => $name,
'start_date' => $start_date,
'end_date' => $end_date,
'start_time' => $start_time,
'end_time' => $end_time,
'isFullDay' =>$isFullDay,
'description' => $description,
'calendar_type' => $calendar_type,
'timezone' => $timezone,
'location' => $location,
));
// Event Created and saved to the database
//now we will fetch this events id and store its reminder(if set) to the event_reminder table.
if(!empty($id))
{
if (!empty($request->reminder_type && $request->reminder_number && $request->reminder_duration)) {
DB::table('event_reminders')->where('id', $id)->update([
'event_id' => $id,
'type' => $request->reminder_type,
'number'=> $request->reminder_number,
'duration' => $request->reminder_duration
]);
}
}
else{
DB::table('event_reminders')->insert([
'type' => $request->reminder_type,
'number'=> $request->reminder_number,
'duration' => $request->reminder_duration
]);
}
return redirect()->back();
}
Route:
Route::post('/event/update/{id}', 'EventTasksController#updateEvent');
Form attributes :
<form action="/event/update/{{$event->id}}" method="POST">
{{ method_field('PATCH')}}
i'm calling the same update function inside my calendar page and it working fine there. Don't know why it doesn't work here.
Check the routeing method.
Route::patch('/event/update/{id}', 'EventTasksController#updateEvent');
patch should be the method called on route facade.
Change your route to patch:
Route::patch('/event/update/{id}', 'EventTasksController#updateEvent');
For your comment:
You can send the method to the ajax call by something like data-method attribute on the element you click on,take the method and use it in your ajax call. see this question/answer for help. How to get the data-id attribute?

Magento create order programmatically with downloadable product

I have been successful creating orders with a Custom controller and all works well. My issue is i need to add the ability to create orders with downloadable product. I would just like to be pointed on where to start.
Controller is handling all the set up and the order save. Is there a Action or something I need to hit for the customer to be able to access his/her downloads?
Try the below Code, please go threw comments.
<?php
require_once 'app/Mage.php';
Mage::app();
$customer = Mage::getModel("customer/customer")
->setWebsiteId(Mage::app()->getStore()->getWebsiteId())
->loadByEmail($data['email']);
if(!$customer->getId()) {
$customer->setEmail($email); //enter Email here
$customer->setFirstname($fname); //enter Lirstname here
$customer->setLastname($lname); //enter Lastnamre here
$customer->setPassword(password); //enter password here
$customer->save();
}
$storeId = $customer->getStoreId();
$quote = Mage::getModel('sales/quote')
->setStoreId($storeId);
$quote->assignCustomer($customer);
// add product(s)
$product = Mage::getModel('catalog/product')->load(186); //product id
/*$buyInfo = array(
'qty' => 1,
'price'=>0
// custom option id => value id
// or
// configurable attribute id => value id
);*/
$params = array();
$links = Mage::getModel('downloadable/product_type')->getLinks( $product );
$linkId = 0;
foreach ($links as $link) {
$linkId = $link->getId();
}
//$params['product'] = $product;
$params['qty'] = 1;
$params['links'] = array($linkId);
$request = new Varien_Object();
$request->setData($params);
//$quoteObj->addProduct($productObj , $request);
/* Bundled product options would look like this:
$buyInfo = array(
"qty" => 1,
"bundle_option" = array(
"123" => array(456), //optionid => array( selectionid )
"124" => array(235)
)
); */
//$class_name = get_class($quote);
//Zend_Debug::dump($class_name);
$quote->addProduct($product, $request);
$addressData = array(
'firstname' => 'Vagelis', //you can also give variables here
'lastname' => 'Bakas',
'street' => 'Sample Street 10',
'city' => 'Somewhere',
'postcode' => '123456',
'telephone' => '123456',
'country_id' => 'US',
'region_id' => 12, // id from directory_country_region table if it Country ID is IN (India) region id is not required
);
$billingAddress = $quote->getBillingAddress()->addData($addressData);
$shippingAddress = $quote->getShippingAddress()->addData($addressData);
/*$shippingAddress->setCollectShippingRates(true)->collectShippingRates()
->setShippingMethod('flatrate_flatrate')
->setPaymentMethod('checkmo');*/
/* Free shipping would look like this: */
$shippingAddress->setFreeShipping( true )
->setCollectShippingRates(true)->collectShippingRates()
->setShippingMethod('freeshipping_freeshipping')
->setPaymentMethod('checkmo'); /* shipping details is not required for downloadable product */
$quote->setCouponCode('ABCD'); // if required
/* Make Sure Your Check Money Order Method Is Enable */
/*if the product value is zero i mean free product then the payment method is free array('method' => 'free')*/
$quote->getPayment()->importData(array('method' => 'checkmo'));
$quote->collectTotals()->save();
$service = Mage::getModel('sales/service_quote', $quote);
$service->submitAll();
$order = $service->getOrder();
printf("Order Created Successfully %s\n", $order->getIncrementId());

How do I use setPage() in an non-EAV model in Magento for pagination/limiting?

I need to get $collection->setPage(0, 10); to work on my non-EAV model and it doesn't work. I've tried and $matches->getSelect()->setPage(0, 10); and it doesn't help.
The setPage() method only works for EAV based collection in Magento because it is defined in Mage_Eav_Model_Entity_Collection_Abstract class...
public function setPage($pageNum, $pageSize)
{
$this->setCurPage($pageNum)
->setPageSize($pageSize);
return $this;
}
As you can see, its a nice shorthand utility that is available to EAV based collections. For your non EAV based collection you can create your own version of this in your collection class or use the more verbose syntax for setting the page number and size in your client code when initialising the collection:
$collection->setCurPage($pageNum)
->setPageSize($pageSize)
;
public function updateIndex()
{
$productsCollection = Mage::getModel('catalog/product')->getCollection()
->addAttributeToSelect(array('name', 'image', 'url_key', 'price', 'visibility'));
$productsCollection->setPageSize(100);
$pages = $productsCollection->getLastPageNumber();
$currentPage = 1;
do {
$productsCollection->setCurPage($currentPage);
$productsCollection->load();
foreach ($productsCollection as $_product) {
$insertData = array(
'entity_id' => $_product->getId(),
'title' => $_product->getName(),
'image' => $_product->getImage(),
'url' => $_product->getUrlKey(),
'price' => $_product->getFinalPrice(),
);
$this->_getWriteAdapter()->insertOnDuplicate(
$this->getTable('atwix_sonar/suggestions'),
$insertData,
array('title', 'image', 'url', 'price')
);
}
$currentPage++;
//clear collection and free memory
$productsCollection->clear();
} while ($currentPage <= $pages);
}
See this complete example, it illustrates exactly how to use magento collection pager functions.
Source : http://www.atwix.com/magento/working-with-large-collections/

Resources