Can't get POST data with AJAX - ajax

I would like to show 4 objects in a page, with a "load more" button which show 4 more object each time we click.
I try to adapt a PHP script which works(tested) to Symfony.
The problem is that I can't get the POST data (a page number) in my Symfony function, even if I can see it in the chrome developer toolbar...
My controller:
<?php
/**
* Content controller.
*
* #Route("content")
*/
class ContentController extends Controller
{
/**
* Lists all software.
*
* #Route("/software", name="content_software")
* #Method({"POST", "GET"})
*/
public function softwareAction(Request $request)
{
if ($request->request->get('page')){
$page_number = filter_var($_POST["page"], FILTER_SANITIZE_NUMBER_INT,
FILTER_FLAG_STRIP_HIGH);
$item_per_page = 4;
$position = (($page_number-1) * $item_per_page);
$contents = $this->getRepo()->findBy(array(),null,$item_per_page,$position);
}
else
{
$contents = "didn't work";
}
return $this->render('content/index.html.twig', array(
'contents' => $contents
));
}
}
index.html.twig :
{% extends 'loicCoreBundle::Default/layout.html.twig' %}
{% block body %}
{{ dump(contents) }}
<script type="text/javascript">
var track_page = 1; //track user click as page number, right now page number is 1
load_contents(track_page); //load content
$("#load_more_button").click(function (e) { //user clicks on button
track_page++; //page number increment everytime user clicks load button
load_contents(track_page); //load content
});
//Ajax load function
function load_contents(track_page){
$.post( "{{ path('content_software') }}", {'page': track_page}, function(data){
if(data.trim().length == 0){
//display text and disable load button if nothing to load
$("#load_more_button").text("No more records!").prop("disabled", true);
}
});
}
</script>
{% endblock %}

I'm not sure where your errors are coming from, I've done a similar test which just works (no problems with $request->request->get()).
You are however loading a full template (index.html) for each sub request as well. Usually you want to separate calls like this into api like methods, however for simple things its a bit silly.
Here is an expanded/ updated version of what I tested, I avoided post data all together and just used the method as switch. This worked fine so try and figure out where you went wrong using this as reflection (or whatever you like to do with it). Note this uses a simple PHP range array for test data, not entities but it should remain the same principle.
Controller
/**
* #Route(
* "software/{page}/{limit}",
* name="content_software",
* requirements = {
* "page": "[1-9]\d*",
* "limit": "[1-9]\d*"
* }
* )
*/
public function softwareAction(Request $request, $page = 1, $limit = 4) {
if ($request->isMethod('POST')) {
// replace these two lines with database logic (SELECT & LIMIT)
$start = ($page - 1) * $limit;
$items = array_slice(range(1, 10), $start, $limit); // Just using a simple item array [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] as test data
$content = '';
foreach ($items as $item) {
$content .= $this->get('twig')->render('someItemTemplate.html.twig', ['item' => $item]);
}
return new Response($content);
} else {
// alternatively you can send out the default items here for the first get request
// and use the same item template above with {% embed %} to render them in this template
return $this->render('someTemplate.html.twig');
}
}
someTemplate.html.twig
<html>
<head>
<title>Cake or death?</title>
</head>
<body>
<ul id="put-the-things-here"></ul>
<button id="next_please">Ehh cake please!</button>
<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
<script>
var pageTracker = 1,
$next = $("#next_please"),
$target = $('#put-the-things-here');
load_contents(pageTracker);
$next.click(function (e) {
load_contents(++pageTracker);
});
function load_contents(page) {
// using post just for the request method (page is in the url)
$.post("{{ path('content_software') }}/" + page,
function (data) {
if (data) {
$target.append(data);
} else {
$target.append('<li>We are out of cake.</li>');
$next.attr('disabled', true);
}
}
);
}
</script>
</body>
</html>
someItemTemplate.twig
<li>Cake: {{ item }}</li>

try this:
$request->request->get('page')
Instead of this:
$request->request->has('page')
If it doesn't work try to:
var_dump($request->request->all());
And check the variables

I think too the problem comes from routes.
Error message when I use only "POST" method :
"No route found for "GET /content/software": Method Not Allowed (Allow: POST, DELETE)".
Because when I arrive on my page by clicking a link , I arrive with a GET method.
However, when I click on my "load more" button the AJAX works and I can see in my symfony debugbar that I get POST variable:
The problem is when I first arrive on my page I think.
#Jenne van der Meer: Thank you but I would like not to use GET parameters.
I add my full controller code, in case of:
/**
* Content controller.
*
* #Route("content")
*/
class ContentController extends Controller
{
public function getRepo(){
$em = $this->getDoctrine()->getManager();
$repo = $em->getRepository('loicContentBundle:Content');
return $repo;
}
// private $theRepo = getDoctrine()->getManager()->getRepository('loicContentBundle:Content');
/**
* Lists all content entities.
*
* #Route("/", name="content_index")
* #Method("GET") */
public function indexAction(Request $request)
{
$contents = $this->getRepo()->findAll();
$this->denyAccessUnlessGranted('ROLE_USER', null, 'Unable to access this page!');
$formFilter = $this->createFormBuilder()
->add('_', EntityType::class,array(
'class' => 'loicFilterBundle:Filter',
'multiple' => true,
'expanded' => true,
'choice_label' => function($value) {
return ($value->getName());
},
))
->add('Appliquer filtres', SubmitType::class)
->getForm();
$formFilter->handleRequest($request);
$data = '';
if ($formFilter->isSubmitted() && $formFilter->isValid()) {
$data = $formFilter->getData();
$data = $data['_']->toArray();
$contents = $this->getRepo()->findAll();
}
else
{$contents = $this->getRepo()->findAll();
}
return $this->render('content/index.html.twig', array(
'contents' => $contents,'formFilter' => $formFilter->createView(),'request' => $request
));
}
public function contentAction($categoryId)
{
$contents= $this->getRepo()->findBy(
array('contentCategorycontentCategory' => $categoryId),
null,
4
);
return $contents;
}
/**
* Lists all software.
*
* #Route("/software", name="content_software")
*/
public function softwareAction(Request $request)
{
var_dump($request->request->all());
$bla = $request->request->get('page');
if ($request->request->get('page')){
$page_number = filter_var($_POST["page"], FILTER_SANITIZE_NUMBER_INT,
FILTER_FLAG_STRIP_HIGH);
$item_per_page = 4;
$position = (($page_number-1) * $item_per_page);
$contents = $this->getRepo()->findBy(array(),null,$item_per_page,$position);
}
else
{
$contents = "didn't work";
}
return $this->render('content/index.html.twig', array(
'contents' => $contents,'bla' => $bla
));
}
/**
* Lists all videos.
*
* #Route("/videos", name="content_videos")
* #Method("GET")
*/
public function videoAction()
{
$contents = $this->contentAction(5);
return $this->render('content/index.html.twig', array(
'contents' => $contents,
));
}
/**
* Lists all testimonies.
*
* #Route("/testimonies", name="content_testimonies")
* #Method("GET")
*/
public function testimoniesAction()
{
$contents = $this->contentAction(8);
return $this->render('content/index.html.twig', array(
'contents' => $contents,
));
}
/**
* Lists all whiteBooks.
*
* #Route("/whiteBooks", name="content_whiteBooks")
* #Method("GET")
*/
public function whiteBooksAction()
{
$contents = $this->contentAction(3);
return $this->render('content/index.html.twig', array(
'contents' => $contents,
));
}
/**
* Lists all actuality.
*
* #Route("/actuality", name="content_actuality")
* #Method("GET")
*/
public function actualityAction()
{
$contents = $this->contentAction(6);
return $this->render('content/index.html.twig', array(
'contents' => $contents,
));
}
/**
* Lists all webinar.
*
* #Route("/webinar", name="content_webinar")
* #Method("GET")
*/
public function webinarAction()
{
$contents = $this->contentAction(4);
return $this->render('content/index.html.twig', array(
'contents' => $contents,
));
}
/**
* Lists all blog posts.
*
* #Route("/blog", name="content_blog")
* #Method("GET")
*/
public function blogAction()
{
$contents = $this->contentAction(7);
return $this->render('content/index.html.twig', array(
'contents' => $contents,
));
}
/**
* Creates a new content entity.
*
* #Route("/new", name="content_new")
* #Method({"GET", "POST"})
*/
public function newAction(Request $request)
{
$em = $this->getDoctrine()->getManager();
$content = new Content();
$form = $this->createForm('loic\ContentBundle\Form\ContentType', $content);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($content);
$em->flush($content);
return $this->redirectToRoute('content_show', array('id' => $content->getIdcontent()));
}
return $this->render('content/new.html.twig', array(
'content' => $content,
'form' => $form->createView(),
));
}
/**
* Displays a form to edit an existing content entity.
*
* #Route("/{id}/edit", name="content_edit")
* #Method({"GET", "POST"})
*/
public function editAction(Request $request, Content $content)
{
$deleteForm = $this->createDeleteForm($content);
$editForm = $this->createForm('loic\ContentBundle\Form\ContentType', $content);
$editForm->handleRequest($request);
if ($editForm->isSubmitted() && $editForm->isValid()) {
$this->getDoctrine()->getManager()->flush();
return $this->redirectToRoute('content_edit', array('id' => $content->getIdcontent()));
}
return $this->render('content/edit.html.twig', array(
'content' => $content,
'edit_form' => $editForm->createView(),
'delete_form' => $deleteForm->createView(),
));
}
/**
* Deletes a content entity.
*
* #Route("/{id}", name="content_delete")
* #Method("DELETE")
*/
public function deleteAction(Request $request, Content $content)
{
$form = $this->createDeleteForm($content);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->remove($content);
$em->flush();
}
return $this->redirectToRoute('content_index');
}
/**
* Creates a form to delete a content entity.
*
* #param Content $content The content entity
*
* #return \Symfony\Component\Form\Form The form
*/
private function createDeleteForm(Content $content)
{
return $this->createFormBuilder()
->setAction($this->generateUrl('content_delete', array('id' => $content->getIdcontent())))
->setMethod('DELETE')
->getForm()
;
}
}
My Bundle/Resources/config/routing.yml file is empty.

Related

A non-numeric value encountered Laravel 5

It's been a while since I'm getting the same Error after I installed the Laravel Voyager package, when I wanted to access the /admin it shows this error as mentioned in the picture.
I didn't get where the problem come from..
Please help
A non-numeric value encountered
Here is my code :
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use DB;
use Auth;
class HomeController extends Controller
{
/**
* Create a new controller instance.
*
* #return void
*/
/**
* Show the application dashboard.
*
* #return \Illuminate\Http\Response
*/
public function index($page = 1)
{
$DBpostscheck= DB::table('posts')->where('whocanseethis', 'Everyone')->select('id')->get();
$postcount = 0;
$pageminus = $page - 1;
$toskip = $pageminus * 20;
foreach($DBpostscheck as $post) {
$postcount++;
}
$pagecount = ceil($postcount / 20);
if($page > 1) {
$previouspage = $page - 1;
} else {
$previouspage = false;
}
$nextpage = $page + 1;
$DBposts = DB::table('posts')->where('whocanseethis', 'Everyone')->take(20)->skip($toskip)->get();
$DBcategories = DB::table('categories')->get();
//need for poll
$allvotes = 0;
$DBpoll = DB::table('poll')->get();
$DBvotes = DB::table('pollvotes')->select('id')->get();
foreach ($DBvotes as $vote) {
$allvotes++;
}
//end
if(isset(Auth::user()->name)) {
$loggedid = Auth::user()->id;
$DBrepliesthreads = DB::table('replies')->where('authorid', $loggedid)->get();
array_set($array, 'arraycreator45236125312', 69);
foreach ($DBrepliesthreads as $replythreads) {
array_push($array, $replythreads->postid);
}
array_forget($array, 'arraycreator45236125312');
$DBactivethreads = DB::table('posts')->where('authorid', $loggedid)->orWhereIn('id', $array)->orderBy('updated_at', 'desc')->select('title', 'id')->groupBy('title')->take(6)->get();
return view('home', ['DBposts' => $DBposts, 'page' => $page, 'pagecount' => $pagecount,'nextpage' => $nextpage, 'previouspage' => $previouspage,
'DBcategories' => $DBcategories, 'DBactivethreads' => $DBactivethreads, 'DBpoll' => $DBpoll,'allvotes' => $allvotes]);
}
return view('home', ['DBposts' => $DBposts, 'page' => $page, 'pagecount' => $pagecount,'nextpage' => $nextpage, 'previouspage' => $previouspage,
'DBcategories' => $DBcategories, 'DBpoll' => $DBpoll, 'allvotes' => $allvotes]);
}
}

Issue in Create Order Pragmatically with multiple products

I am trying to create order with multiple products using below code. code work fine, but one issue is occurring. I don't know why that adding more than one product create an order with just one product and all quantity summed to this.
<?php
namespace Magecomp\Cenpos\Controller\Index;
use Magento\Framework\App\Action;
use Magento\Framework\App\Filesystem\DirectoryList;
use Magento\Store\Model\StoreManagerInterface;
use Magento\Framework\Controller\ResultFactory;
class Display extends \Magento\Framework\App\Action\Action
{
protected $context;
protected $directory_list;
protected $cartRepositoryInterface;
protected $cartManagementInterface;
protected $_orderRepositoryInterface ;
/**
* #var \Magento\Sales\Model\Order\Email\Sender\OrderSender
*/
protected $orderSender;
/**
* #var \Magento\Checkout\Model\Session $checkoutSession
*/
protected $checkoutSession;
protected $_messageManager;
protected $_encryptor;
protected $_scopeConfig;
protected $logger;
public function __construct(
\Magento\Framework\App\Action\Context $context,
\Magento\Framework\App\Filesystem\DirectoryList $directory_list,
\Magento\Store\Model\StoreManagerInterface $storeManager,
\Magento\Catalog\Model\Product $product,
\Magento\Framework\Data\Form\FormKey $formkey,
\Magento\Quote\Model\QuoteFactory $quote,
\Magento\Quote\Model\QuoteManagement $quoteManagement,
\Magento\Customer\Model\CustomerFactory $customerFactory,
\Magento\Customer\Api\CustomerRepositoryInterface $customerRepository,
\Magento\Sales\Model\Service\OrderService $orderService,
\Magento\Customer\Model\Session $currentCustomer,
\Magento\Checkout\Model\Cart $cart,
\Magento\Quote\Api\CartRepositoryInterface $cartRepositoryInterface,
\Magento\Quote\Api\CartManagementInterface $cartManagementInterface,
\Magento\Checkout\Model\Session $checkoutSession,
\Magento\Sales\Model\Order\Email\Sender\OrderSender $orderSender,
\Magento\Framework\Encryption\EncryptorInterface $encryptor,
\Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
//\Magento\Sales\Api\OrderRepositoryInterface $orderRepositoryInterface
) {
$this->directory_list = $directory_list;
$this->_storeManager = $storeManager;
$this->_product = $product;
$this->_formkey = $formkey;
$this->quote = $quote;
$this->quoteManagement = $quoteManagement;
$this->customerFactory = $customerFactory;
$this->customerRepository = $customerRepository;
$this->orderService = $orderService;
$this->_currentCustomer = $currentCustomer;
$this->_cart = $cart;
$this->cartRepositoryInterface = $cartRepositoryInterface;
$this->cartManagementInterface = $cartManagementInterface;
$this->checkoutSession = $checkoutSession;
$this->orderSender = $orderSender;
$this->_encryptor = $encryptor;
$this->_scopeConfig = $scopeConfig;
//$this->_orderRepositoryInterface = $orderRepositoryInterface;
$this->_messageManager = $context->getMessageManager();
parent::__construct($context);
}
public function saveShipping() {
if(isset($_POST['carrier_code']))
{
$_SESSION['carrier_code'] = $_POST['carrier_code'];
}
return true;
}
public function execute()
{
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$cart = $objectManager->get('\Magento\Checkout\Model\Cart');
$shippingAddress = $cart->getQuote()->getShippingAddress();
$shippingAddressData = $shippingAddress->getData();
$Response = $_GET;
if($Response['message'] == "Approved" && $Response['result'] == "0") {
$store=$this->_storeManager->getStore();
$websiteId = $this->_storeManager->getStore()->getWebsiteId();
$customer=$this->customerFactory->create();
$customer->setWebsiteId($websiteId);
$customer->loadByEmail($shippingAddressData['email']);// load customet by email address
if(!$customer->getEntityId()){
//If not avilable then create this customer
$customer->setWebsiteId($websiteId)
->setStore($store)
->setFirstname($shippingAddressData['firstname'])
->setLastname($shippingAddressData['lastname'])
->setEmail($shippingAddressData['email'])
->setPassword($shippingAddressData['email']);
$customer->save();
$customer= $this->customerRepository->getById($customer->getEntityId());
}
//init the quote
$cart_id = $this->cartManagementInterface->createEmptyCart();
$cart = $this->cartRepositoryInterface->get($cart_id);
$cart->setStore($store);
// if you have already had the buyer id, you can load customer directly
$customer= $this->customerRepository->getById($customer->getEntityId());
$cart->setCurrency();
$cart->assignCustomer($customer); //Assign quote to customer
$productInfo = $this->_cart->getQuote()->getAllItems();
//add items in quote
foreach($productInfo as $item){
$product=$this->_product->load($item->getProductId());
$product->setPrice($item->getPrice());
$cart->addProduct(
$product,
intval($item->getQty())
);
}
$addressData = array(
'firstname' => $shippingAddressData['firstname'],
'lastname' => $shippingAddressData['lastname'],
'street' => $shippingAddressData['street'],
'city' => $shippingAddressData['city'],
'postcode' => $shippingAddressData['postcode'],
'telephone' => $shippingAddressData['telephone'],
'country_id' => $shippingAddressData['country_id'],
'region_id' => $shippingAddressData['region_id'],
'region' => $shippingAddressData['region'],
);
//set shipping and billing address
$quote = $this->quote->create();
$cart->getBillingAddress()->addData($addressData);
$cart->getShippingAddress()->addData($addressData);
if(isset($_SESSION['carrier_code'])) {
$shipping_method = $_SESSION['carrier_code'];
} else {
$session = $this->_objectManager->get('Magento\Checkout\Model\Session');
$shipping_method = $session->getQuote()->getShippingAddress()->getShippingMethod();
}
$shippingAddress = $cart->getShippingAddress();
$shippingAddress->setCollectShippingRates(true)
->collectShippingRates()
->setShippingMethod($shipping_method);
unset($_SESSION['carrier_code']);
$cart->setPaymentMethod('cenpos'); //payment method
//#todo insert a variable to affect the invetory
$cart->setInventoryProcessed(false);
$card_type_code = "VI";
$cart->getPayment()->importData(
[
'method' => 'cenpos',
'cc_type' => $card_type_code,
'cc_number' => '4893772408728522',
'cc_cid' => '341',
'cc_exp_month' => '02',
'cc_exp_year' => '2022'
]
);
// Collect total and save
$cart->collectTotals();
// Submit the quote and create the order
$cart->save();
$cart = $this->cartRepositoryInterface->get($cart->getId());
$order_id = $this->cartManagementInterface->placeOrder($cart->getId());
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$orderRepository = $objectManager->create('Magento\Sales\Model\Order')->load($order_id);
$orderRepository->save();
$orderRepository->setEmailSent(true);
$this->checkoutSession->setForceOrderMailSentOnSuccess(true);
$this->orderSender->send($orderRepository, true);
$resultRedirect = $this->resultFactory->create(ResultFactory::TYPE_REDIRECT);
$resultRedirect->setUrl('http://m2gymtest.tpesonline.com/checkout/onepage/success');
return $resultRedirect;
}
}
}
Is there any problem in script? Or can it be server issue as the issue starts occurring after server changes.It was working properly before some days.
Use \Magento\Catalog\Model\ProductFactory $product instead of \Magento\Catalog\Model\Product $product in __construct() argument.
And Use
$product = $this->_product->create()->setStoreId($storeId)->load($item->getId());
to load the product instead of
$product=$this->_product->load($item->getProductId());
Hope this will help .

Custom filter API Platform not working

I am trying to implement a custom or-filter in API Platform. But for some reason it is not loading. Find below my configuration.
This is my filter:
<?php
namespace AppBundle\Filter;
use ApiPlatform\Core\Bridge\Doctrine\Orm\Filter\AbstractFilter;
use ApiPlatform\Core\Bridge\Doctrine\Orm\Util\QueryNameGeneratorInterface;
use Doctrine\ORM\QueryBuilder;
use Doctrine\Common\Annotations\AnnotationReader;
final class SearchFilter extends AbstractFilter
{
protected function filterProperty(string $property, $value, QueryBuilder $queryBuilder, QueryNameGeneratorInterface $queryNameGenerator, string $resourceClass, string $operationName = null)
{
if ($property === 'search') {
$this->logger->info('Search for: ' . $value);
} else {
return;
}
$reader = new AnnotationReader();
$annotation = $reader->getClassAnnotation(new \ReflectionClass(new $resourceClass), \AppBundle\Filter\SearchAnnotation::class);
if (!$annotation) {
throw new \HttpInvalidParamException('No Search implemented.');
}
$parameterName = $queryNameGenerator->generateParameterName($property);
$search = [];
$mappedJoins = [];
foreach ($annotation->fields as $field)
{
$joins = explode(".", $field);
for ($lastAlias = 'o', $i = 0, $num = count($joins); $i < $num; $i++) {
$currentAlias = $joins[$i];
if ($i === $num - 1) {
$search[] = "LOWER({$lastAlias}.{$currentAlias}) LIKE LOWER(:{$parameterName})";
} else {
$join = "{$lastAlias}.{$currentAlias}";
if (false === array_search($join, $mappedJoins)) {
$queryBuilder->leftJoin($join, $currentAlias);
$mappedJoins[] = $join;
}
}
$lastAlias = $currentAlias;
}
}
$queryBuilder->andWhere(implode(' OR ', $search));
$queryBuilder->setParameter($parameterName, '%' . $value . '%');
}
/**
* #param string $resourceClass
* #return array
*/
public function getDescription(string $resourceClass): array
{
$reader = new AnnotationReader();
$annotation = $reader->getClassAnnotation(new \ReflectionClass(new $resourceClass), \AppBundle\Filter\SearchAnnotation::class);
$description['search'] = [
'property' => 'search',
'type' => 'string',
'required' => false,
'swagger' => ['description' => 'Filter on ' . implode(', ', $annotation->fields)],
];
return $description;
}
}
In api_filters.yml:
driver.custom_search_filter:
class: 'AppBundle\Filter\SearchFilter'
autowire: true
tags: [ { name: 'api_platform.filter' } ]
In my annotation file:
<?php
namespace AppBundle\Filter;
use Doctrine\Common\Annotations\Annotation;
use Doctrine\Common\Annotations\Annotation\Target;
use Doctrine\Common\Annotations\AnnotationException;
/**
* #Annotation
* #Target("CLASS")
*/
final class SearchAnnotation
{
public $fields = [];
/**
* Constructor.
*
* #param array $data Key-value for properties to be defined in this class.
* #throws AnnotationException
*/
public function __construct(array $data)
{
if (!isset($data['value']) || !is_array($data['value'])) {
throw new AnnotationException('Options must be a array of strings.');
}
foreach ($data['value'] as $key => $value) {
if (is_string($value)) {
$this->fields[] = $value;
} else {
throw new AnnotationException('Options must be a array of strings.');
}
}
}
}
And finally in my entity:
/**
* A driver that bring meals from hub to customer.
*
*
* #ApiResource(
* attributes={
* "filters"={"driver.search_filter","driver.custom_search_filter"},
* "denormalization_context"={"groups"={"post_driver"}}
* }
* )
* #Searchable({"firstName"})
*
* #ORM\Entity
* #ORM\Table(name="vendor_driver")
*/
class Driver
{
It is exactly as according to the issue that was reported here:
https://github.com/api-platform/core/issues/398
I am not getting any errors, but the filter is simply not working. I am seeing it in Swagger. But when I enter a value in Swagger, the db returns all entities. Its never reaching the filterProperty method.
Does anyone have an idea?
I've just managed to get this working by removing the autowiring, e.g.
my.custom_search_filter:
class: AppBundle\Filter\CustomSearchFilter
arguments:
- '#doctrine'
- '#request_stack'
- '#logger'
tags: [ { name: 'api_platform.filter', id: 'search' } ]
Hope that helps.
Did you import your custom filter in the Driver entity? In Regexp example of custom filter and here they are explicitly import their custom filters like:
use AppBundle\Filter\SearchAnnotation as Searchable;
/**
* #Searchable({"name", "description", "whatever"})
*/
class Product
{

How to use pagination in collection fetched by sortBy and where operators?

I need pagination for my collection in which I have to apply lots of filters. But I'm unable to achieve this. I'm new to laravel so please show me the right way.
My controller:
public function index(Request $request)
{
$view = $request['view'] ? $request['view'] :'grid';
$purpose = $request['purpose'] ? $request['purpose'] : 'rent';
$sort = $request['sort'] ? $request['sort'] : 'asc';
$properties = $properties->where('purpose' , $purpose);
if($sort == 'asc');
$properties = $properties->sortBy('price');
else
$properties = $properties->sortByDesc('price');
$properties = $properties->paginate(5);
return view('frontend.properties.index', [ 'view'=>$view , 'properties' => $properties , 'request'=> $request->all() ]);
}
I have had this issue and in order to solve that, I have created a trait called PaginateCollection:
/*
* Paginate the Laravel Collection before and/or after filtering.
*
*/
trait PaginateCollection
{
/**
* Paginate the collection.
*
* #param \Illuminate\Support\Collection|\Illuminate\Database\Eloquent\Collection $collection
* #param integer $perPage
* #param integer $currentPage
* #return \Illuminate\Pagination\LengthAwarePaginator
*/
public function paginate($collection, $perPage = 10, $currentPage = 1)
{
$offSet = ($currentPage * $perPage) - $perPage;
$otherParams = [
'path' => request()->url(),
'query' => request()->query()
];
return new LengthAwarePaginator(
$collection->forPage(Paginator::resolveCurrentPage() , $perPage),
$collection->count(),
$perPage,
Paginator::resolveCurrentPage(),
$otherParams
);
}
}
Perhaps, this should help you out.

yii user: upload image on registration form

I want to upload profile picture in yii user. By so much digging, i came to know that i need to make a profilefield, which i did and called "picture" and then in view of modules/user/registrtaion i need to write this code, given below is my registration view file.
<?php
$profileFields=$profile->getFields();
if ($profileFields) {
foreach($profileFields as $field) {
?>
<div class="row">
<?php
if ($widgetEdit = $field->widgetEdit($profile)) {
echo $widgetEdit;
} elseif ($field->range) {
echo $form->dropDownListControlGroup($profile,$field->varname,Profile::range($field->range));
} elseif ($field->field_type=="TEXT") {
echo$form->textArea($profile,$field->varname,array('rows'=>6, 'cols'=>50));
}
// I added this below elseif for picture upload
elseif ($field->field_type=="VARCHAR" && $field->field_size=="500") {
echo$form->fileField($profile,$field->varname,array('rows'=>6, 'cols'=>50));
}else {
echo $form->textFieldControlGroup($profile,$field->varname,array('size'=>60,'maxlength'=>(($field->field_size)?$field->field_size:255)));
}
?>
and i am hanlding this profile picture in modules/model/registration.php like this. Given below is the code.
<?php
class RegistrationForm extends User {
public $verifyPassword;
public $verifyCode;
public function rules() {
$rules = array(
array('username, password, verifyPassword, email', 'required'),
array('username', 'length', 'max'=>20, 'min' => 3,'message' => UserModule::t("Incorrect username (length between 3 and 20 characters).")),
array('password', 'length', 'max'=>128, 'min' => 4,'message' => UserModule::t("Incorrect password (minimal length 4 symbols).")),
array('email', 'email'),
array('username', 'unique', 'message' => UserModule::t("This user's name already exists.")),
array('email', 'unique', 'message' => UserModule::t("This user's email address already exists.")),
//array('verifyPassword', 'compare', 'compareAttribute'=>'password', 'message' => UserModule::t("Retype Password is incorrect.")),
array('username', 'match', 'pattern' => '/^[A-Za-z0-9_]+$/u','message' => UserModule::t("Incorrect symbols (A-z0-9).")),
// adding this liine
array('picture', 'file','types'=>'jpg, gif, png', 'allowEmpty'=>true, 'on'=>'update'), //
);
if (!(isset($_POST['ajax']) && $_POST['ajax']==='registration-form')) {
array_push($rules,array('verifyCode', 'captcha', 'allowEmpty'=>!UserModule::doCaptcha('registration')));
}
array_push($rules,array('verifyPassword', 'compare', 'compareAttribute'=>'password', 'message' => UserModule::t("Retype Password is incorrect.")));
return $rules;
}
}
and finally in the controller i handle the picture like this given below is the code.
<?php
class RegistrationController extends Controller
{
public $defaultAction = 'registration';
/**
* Declares class-based actions.
*/
public function actions()
{
return array(
'captcha'=>array(
'class'=>'CCaptchaAction',
'backColor'=>0xFFFFFF,
),
);
}
/**
* Registration user
*/
public function actionRegistration() {
$model = new RegistrationForm;
$profile=new Profile;
$profile->regMode = true;
// ajax validator
if(isset($_POST['ajax']) && $_POST['ajax']==='registration-form')
{
echo UActiveForm::validate(array($model,$profile));
Yii::app()->end();
}
if (Yii::app()->user->id) {
$this->redirect(Yii::app()->controller->module->profileUrl);
} else {
if(isset($_POST['RegistrationForm'])) {
// handling picture
$rnd = rand(0, 9999); // generate random number between 0-9999
$model->attributes = $_POST['RegistrationForm'];
$uploadedFile = CUploadedFile::getInstance($model, 'picture');
$fileName = "{$rnd}-{$uploadedFile}"; // random number + file name
$model->picture = $fileName;
if ($model->save()) {
$uploadedFile->saveAs(Yii::app()->basePath . '/../img/' . $fileName);
$this->redirect(array('view', 'id' => $model->id));
}
// hanlding picture ends
$profile->attributes=((isset($_POST['Profile'])?$_POST['Profile']:array()));
if($model->validate()&&$profile->validate())
{
$soucePassword = $model->password;
$model->activkey=UserModule::encrypting(microtime().$model->password);
$model->password=UserModule::encrypting($model->password);
$model->verifyPassword=UserModule::encrypting($model->verifyPassword);
$model->superuser=0;
$model->status=((Yii::app()->controller->module->activeAfterRegister)?User::STATUS_ACTIVE:User::STATUS_NOACTIVE);
if ($model->save()) {
$profile->user_id=$model->id;
$profile->save();
if (Yii::app()->controller->module->sendActivationMail) {
$activation_url = $this->createAbsoluteUrl('/user/activation/activation',array("activkey" => $model->activkey, "email" => $model->email));
UserModule::sendMail($model->email,UserModule::t("You registered from {site_name}",array('{site_name}'=>Yii::app()->name)),UserModule::t("Please activate you account go to {activation_url}",array('{activation_url}'=>$activation_url)));
}
if ((Yii::app()->controller->module->loginNotActiv||(Yii::app()->controller->module->activeAfterRegister&&Yii::app()->controller->module->sendActivationMail==false))&&Yii::app()->controller->module->autoLogin) {
$identity=new UserIdentity($model->username,$soucePassword);
$identity->authenticate();
Yii::app()->user->login($identity,0);
$this->redirect(Yii::app()->controller->module->returnUrl);
} else {
if (!Yii::app()->controller->module->activeAfterRegister&&!Yii::app()->controller->module->sendActivationMail) {
Yii::app()->user->setFlash('registration',UserModule::t("Thank you for your registration. Contact Admin to activate your account."));
} elseif(Yii::app()->controller->module->activeAfterRegister&&Yii::app()->controller->module->sendActivationMail==false) {
Yii::app()->user->setFlash('registration',UserModule::t("Thank you for your registration. Please {{login}}.",array('{{login}}'=>CHtml::link(UserModule::t('Login'),Yii::app()->controller->module->loginUrl))));
} elseif(Yii::app()->controller->module->loginNotActiv) {
Yii::app()->user->setFlash('registration',UserModule::t("Thank you for your registration. Please check your email or login."));
} else {
Yii::app()->user->setFlash('registration',UserModule::t("Thank you for your registration. Please check your email."));
}
$this->refresh();
}
}
} else $profile->validate();
}
$this->render('/user/registration',array('model'=>$model,'profile'=>$profile));
}
}
}
so the problem is,, when i enter the details on registraion form and upload a picture i get this error Property "RegistrationForm.picture" is not defined. The problem lies in controller line number 45 which is
$model->picture = $fileName;
I already have picture field in "profiles" table. But the thing is i am totally confused, and neither at yii framework forum nor at stackoverflow i found a proper documentation over this thing. Please help.
My profile.php (model) code
<?php
class Profile extends UActiveRecord
{
/**
* The followings are the available columns in table 'profiles':
* #var integer $user_id
* #var boolean $regMode
*/
public $regMode = false;
private $_model;
private $_modelReg;
private $_rules = array();
/**
* Returns the static model of the specified AR class.
* #return CActiveRecord the static model class
*/
public static function model($className=__CLASS__)
{
return parent::model($className);
}
/**
* #return string the associated database table name
*/
public function tableName()
{
return Yii::app()->getModule('user')->tableProfiles;
}
/**
* #return array validation rules for model attributes.
*/
public function rules()
{
if (!$this->_rules) {
$required = array();
$numerical = array();
$float = array();
$decimal = array();
$rules = array();
$model=$this->getFields();
foreach ($model as $field) {
$field_rule = array();
if ($field->required==ProfileField::REQUIRED_YES_NOT_SHOW_REG||$field->required==ProfileField::REQUIRED_YES_SHOW_REG)
array_push($required,$field->varname);
if ($field->field_type=='FLOAT')
array_push($float,$field->varname);
if ($field->field_type=='DECIMAL')
array_push($decimal,$field->varname);
if ($field->field_type=='INTEGER')
array_push($numerical,$field->varname);
if ($field->field_type=='VARCHAR'||$field->field_type=='TEXT') {
$field_rule = array($field->varname, 'length', 'max'=>$field->field_size, 'min' => $field->field_size_min);
if ($field->error_message) $field_rule['message'] = UserModule::t($field->error_message);
array_push($rules,$field_rule);
}
if ($field->other_validator) {
if (strpos($field->other_validator,'{')===0) {
$validator = (array)CJavaScript::jsonDecode($field->other_validator);
foreach ($validator as $name=>$val) {
$field_rule = array($field->varname, $name);
$field_rule = array_merge($field_rule,(array)$validator[$name]);
if ($field->error_message) $field_rule['message'] = UserModule::t($field->error_message);
array_push($rules,$field_rule);
}
} else {
$field_rule = array($field->varname, $field->other_validator);
if ($field->error_message) $field_rule['message'] = UserModule::t($field->error_message);
array_push($rules,$field_rule);
}
} elseif ($field->field_type=='DATE') {
$field_rule = array($field->varname, 'type', 'type' => 'date', 'dateFormat' => 'yyyy-mm-dd', 'allowEmpty'=>true);
if ($field->error_message) $field_rule['message'] = UserModule::t($field->error_message);
array_push($rules,$field_rule);
}
if ($field->match) {
$field_rule = array($field->varname, 'match', 'pattern' => $field->match);
if ($field->error_message) $field_rule['message'] = UserModule::t($field->error_message);
array_push($rules,$field_rule);
}
if ($field->range) {
$field_rule = array($field->varname, 'in', 'range' => self::rangeRules($field->range));
if ($field->error_message) $field_rule['message'] = UserModule::t($field->error_message);
array_push($rules,$field_rule);
}
}
array_push($rules,array(implode(',',$required), 'required'));
array_push($rules,array(implode(',',$numerical), 'numerical', 'integerOnly'=>true));
array_push($rules,array(implode(',',$float), 'type', 'type'=>'float'));
array_push($rules,array(implode(',',$decimal), 'match', 'pattern' => '/^\s*[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?\s*$/'));
$this->_rules = $rules;
}
return $this->_rules;
}
/**
* #return array relational rules.
*/
public function relations()
{
// NOTE: you may need to adjust the relation name and the related
// class name for the relations automatically generated below.
$relations = array(
'user'=>array(self::HAS_ONE, 'User', 'id'),
);
if (isset(Yii::app()->getModule('user')->profileRelations)) $relations = array_merge($relations,Yii::app()->getModule('user')->profileRelations);
return $relations;
}
/**
* #return array customized attribute labels (name=>label)
*/
public function attributeLabels()
{
$labels = array(
'user_id' => UserModule::t('User ID'),
);
$model=$this->getFields();
foreach ($model as $field)
$labels[$field->varname] = ((Yii::app()->getModule('user')->fieldsMessage)?UserModule::t($field->title,array(),Yii::app()->getModule('user')->fieldsMessage):UserModule::t($field->title));
return $labels;
}
private function rangeRules($str) {
$rules = explode(';',$str);
for ($i=0;$i<count($rules);$i++)
$rules[$i] = current(explode("==",$rules[$i]));
return $rules;
}
static public function range($str,$fieldValue=NULL) {
$rules = explode(';',$str);
$array = array();
for ($i=0;$i<count($rules);$i++) {
$item = explode("==",$rules[$i]);
if (isset($item[0])) $array[$item[0]] = ((isset($item[1]))?$item[1]:$item[0]);
}
if (isset($fieldValue))
if (isset($array[$fieldValue])) return $array[$fieldValue]; else return '';
else
return $array;
}
public function widgetAttributes() {
$data = array();
$model=$this->getFields();
foreach ($model as $field) {
if ($field->widget) $data[$field->varname]=$field->widget;
}
return $data;
}
public function widgetParams($fieldName) {
$data = array();
$model=$this->getFields();
foreach ($model as $field) {
if ($field->widget) $data[$field->varname]=$field->widgetparams;
}
return $data[$fieldName];
}
public function getFields() {
if ($this->regMode) {
if (!$this->_modelReg)
$this->_modelReg=ProfileField::model()->forRegistration()->findAll();
return $this->_modelReg;
} else {
if (!$this->_model)
$this->_model=ProfileField::model()->forOwner()->findAll();
return $this->_model;
}
}
}
Your registration form model extends user class. Your field picture is not the attribute of any of them.
It will be the attribute of profile model. You should move your rule to profile model.
Edit: In your profile model put this line
array_push($rules,array('picture', 'file','types'=>'jpg, gif, png', 'allowEmpty'=>true, 'on'=>'update'));
before the line
$this->_rules = $rules;
this code is not tested but it should work.

Resources