Related
I have load an entity using a Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository (new recommandation in SF4) and I want to refresh this entity.
But $entityManager->clear() don't do the job and
$entityManager->refresh($myentity)
told me
Doctrine\ORM\ORMInvalidArgumentException: Entity App\Entity\MyEntity#0000000068ed8bf0000000007dca9dd1 is not managed. An entity is managed if its fetched from the database or registered as new through EntityManager#persist
Here is my repo :
<?php
namespace App\Core\Repository;
use App\Core\Entity\Question;
use App\Core\Entity\QuestionnaireResponse;
use App\Core\Entity\Reponse;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Symfony\Bridge\Doctrine\RegistryInterface;
/**
* #method Reponse|null find($id, $lockMode = null, $lockVersion = null)
* #method Reponse|null findOneBy(array $criteria, array $orderBy = null)
* #method Reponse[] findAll()
* #method Reponse[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
*/
class ReponseRepository extends ServiceEntityRepository
{
/**
* ReponseRepository constructor.
* #param RegistryInterface $registry
*/
public function __construct(RegistryInterface $registry)
{
parent::__construct($registry, Reponse::class);
}
}
Here is my testSetup :
<?php
/*
* Created by Aurelien Jolivard on 24/01/2019.
*/
namespace App\Core\Service;
use Doctrine\Bundle\DoctrineBundle\Command\DropDatabaseDoctrineCommand;
use Doctrine\Bundle\DoctrineBundle\Command\CreateDatabaseDoctrineCommand;
use Doctrine\Bundle\DoctrineBundle\Command\Proxy\CreateSchemaDoctrineCommand;
use Doctrine\Common\DataFixtures\Executor\ORMExecutor;
use Doctrine\Common\DataFixtures\Purger\ORMPurger;
use Doctrine\ORM\EntityManager;
use Symfony\Bridge\Doctrine\ContainerAwareEventManager;
use Symfony\Bridge\Doctrine\DataFixtures\ContainerAwareLoader;
use Symfony\Bundle\FrameworkBundle\Console\Application;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
use Symfony\Component\Console\Input\ArrayInput;
use Symfony\Component\Console\Output\NullOutput;
class TestSetUp extends WebTestCase
{
/** #var EntityManager $em */
protected $em;
protected $application;
public function beginningTest(String $fixtures){
static::$kernel = static::createKernel(array(
'environment' => 'test',
'debug' => 'true'
));
static::$kernel->boot();
$application = new Application(static::$kernel);
// get the Entity Manager
/** #var EntityManager $em */
$em = static::$kernel->getContainer()
->get('doctrine')
->getManager();
/** #var ContainerAwareEventManager $evm */
$evm = $em->getEventManager();
// drop the database
$command = new DropDatabaseDoctrineCommand(static::$kernel->getContainer()->get('doctrine'));
$application->add($command);
$input = new ArrayInput(array(
'command' => 'doctrine:database:drop',
'--force' => true,
'--env' => 'test'
));
$command->run($input, new NullOutput());
// we have to close the connection after dropping the database so we don't get "No database selected" error
$connection = $application->getKernel()->getContainer()->get('doctrine')->getConnection();
if ($connection->isConnected()) {
$connection->close();
}
// create the database
$command = new CreateDatabaseDoctrineCommand(static::$kernel->getContainer()->get('doctrine'));
$application->add($command);
$input = new ArrayInput(array(
'command' => 'doctrine:database:create',
'--env' => 'test'
));
$command->run($input, new NullOutput());
// create schema
$command = new CreateSchemaDoctrineCommand();
$application->add($command);
$input = new ArrayInput(array(
'command' => 'doctrine:schema:create',
'--env' => 'test'
));
$command->run($input, new NullOutput());
// load fixtures
$client = static::createClient();
$loader = new ContainerAwareLoader($client->getContainer());
$loader->loadFromFile(static::$kernel->getProjectDir().$fixtures);
$purger = new ORMPurger($em);
$executor = new ORMExecutor($em, $purger);
$executor->execute($loader->getFixtures());
$this->em = $em;
$this->application = $application;
return ;
}
}
And here is my test where i try to clear data.
<?php
namespace App\Core\Tests\Form\FunctionalTest;
use App\Core\Entity\Questionnaire;
use App\Core\Entity\QuestionnaireResponse;
use App\Core\Entity\Reponse;
use App\Core\Service\TestSetUp;
use Doctrine\ORM\EntityManager;
class QuestionTypeBooleanTest extends TestSetUp
{
public function setUp()
{
$array = $this->beginningTest('/src/Core/DataFixtures/AppFixturesQuestionTypeBoolean.php');
//$this->em = $array[0];
//$this->application = $array[1];
}
/**
* #group question
* #group test_BrouillonPuisSoumission
*/
public function test_BrouillonPuisSoumission()
{
// vérification de l'état de la base de données avant
$client = static::createClient(
array('environment' => 'test') ,
);
$questionnaire = $this->em->getRepository(Questionnaire::class)->findSystemAndValue('system', '123');
$crawler = $client->request(
'GET',
'/questionnaire/'.$questionnaire->getId().'/display/1'
);
$response = $client->getResponse();
$this->assertEquals(200, $response->getStatusCode());
$form = $crawler->selectButton('appbundle_questionnaire_display[draft]')->form();
$form['appbundle_questionnaire_display[1]'] = 0;
$form['appbundle_questionnaire_display[2]'] = 1;
$crawler = $client->submit($form);
$response = $client->getResponse();
$this->assertEquals(302, $response->getStatusCode());
// vérification de l'état de la base de données
$reponse1 = $this->em->getRepository(Reponse::class)->find(1);
$reponse2 = $this->em->getRepository(Reponse::class)->find(2);
$questionnaireResponse = $this->em->getRepository(QuestionnaireResponse::class)->find(1);
$this->assertEquals('0', $reponse1->getValeur(), 'cas1.1');
$this->assertEquals('1', $reponse2->getValeur(), 'cas1.2');
$this->assertEquals(2, $questionnaireResponse->getVersionId());
$crawler = $client->request(
'GET',
'/soumission/1/edit'
);
$response = $client->getResponse();
$this->assertEquals(200, $response->getStatusCode());
$this->assertEquals(0, $crawler->filter('form[name="appbundle_questionnaire_display"]')->form()->getValues()['appbundle_questionnaire_display[1]'], 'cas2.1');
$this->assertEquals(1, $crawler->filter('form[name="appbundle_questionnaire_display"]')->form()->getValues()['appbundle_questionnaire_display[2]'], 'cas2.2');
$form = $crawler->selectButton('appbundle_questionnaire_display[submit]')->form();
$form['appbundle_questionnaire_display[1]'] = 1;
$form['appbundle_questionnaire_display[2]'] = 0;
$crawler = $client->submit($form);
$response = $client->getResponse();
$this->assertEquals(302, $response->getStatusCode());
$this->em->refresh($reponse1);
$this->em->refresh($reponse2);
$this->em->refresh($questionnaireResponse);
//$this->em->clear();
$this->assertEquals('1', $this->em->getRepository(Reponse::class)->find(1)->getValeur(), 'cas3.1');
$this->assertEquals('0', $this->em->getRepository(Reponse::class)->find(2)->getValeur(), 'cas3.2');
$this->assertEquals(3, $this->em->getRepository(QuestionnaireResponse::class)->find(1)->getVersionId());
}
}
How can I do that ?
Doctrine/ORM/EntityManager::clear() method
Clears the EntityManager. All entities that are currently managed by this EntityManager become detached.
Doctrine/ORM/EntityManager::refresh() method
Refreshes the persistent state of an entity from the database, overriding any local changes that have not yet been persisted.
To refresh the entity, just do:
$entityManager->refresh($myentity)
without clear() before it, remove it.
I have found a solution.
The entityManager i get in the TestSetUp is not the one used by the ServiceEntityRepository. This is due to the construct of the ServiceEntityRepository.
Si to clear the good entityManager, i have to call clear on the Repository and not on my EntityManger :
public function test_BrouillonPuisSoumission()
{
// ...
// vérification de l'état de la base de données
$reponseRepository = $this->em->getRepository(Reponse::class);
$questionnaireResponseRepository = $this->em->getRepository(QuestionnaireResponse::class);
$this->em->getRepository(QuestionnaireResponse::class)->find(1)->getVersionId());
$this->assertEquals('0', $reponseRepository->find(1)->getValeur(), 'cas1.1');
$this->assertEquals('1', $reponseRepository->find(2)->getValeur(), 'cas1.2');
$this->assertEquals(2, $questionnaireResponseRepository->find(1)->getVersionId());
// ...
$reponseRepository->clear();
$questionnaireResponseRepository->clear();
$this->assertEquals('1', $reponseRepository->find(1)->getValeur(), 'cas3.1');
$this->assertEquals('0', $reponseRepository->find(2)->getValeur(), 'cas3.2');
$this->assertEquals(3, $questionnaireResponseRepository->find(1)->getVersionId());
}
how i want to show customer groups in my custome module, like "NOT LOGGED IN - General" or "NOT LOGGED IN - General - Wholesale - Retailer",
this is my code in grid
$this->addColumn(
'customer_group',
[
'header' => __('Customer Groups'),
'index' => 'customer_group',
'class' => 'customer_group',
'type' => 'options',
'renderer' => 'Rendy\ModuleWarehouse\Block\Adminhtml\Warehouse\Renderer\CustomerGroups'
]
);
and this is my code CustomerGroups
namespace Rendy\ModuleWarehouse\Block\Adminhtml\Warehouse\Renderer;
use Magento\Framework\DataObject;
class CustomerGroups extends \Magento\Backend\Block\Widget\Grid\Column\Renderer\AbstractRenderer
{
protected $_customerGroup;
public function __construct(
\Magento\Backend\Block\Context $context,
\Magento\Customer\Model\ResourceModel\Group\Collection $customerGroup,
array $data = []
) {
$this->_customerGroup = $customerGroup;
parent::__construct($context, $data);
}
/**
* Get customer groups
*
* #return array
*/
public function render(DataObject $row) {
$customerGroups = $this->_customerGroup->toOptionArray();
array_unshift($customerGroups, array('value'=>'', 'label'=>'Any'));
}
}
thank you
Ever get this solved? You could use \Magento\Customer\Model\GroupFactory in your construct:
public function __construct(
\Magento\Backend\Block\Context $context,
\Magento\Customer\Model\GroupFactory $groupFactory
array $data = []
) {
$this->_groupFactory = $groupFactory;
parent::__construct($context, $data);
}
It is nice because you can then do in your render function:
$collection = $this->groupFactory->create()->getCollection();
foreach ($collection as $group) {
echo "group id ".$group->getId();
echo "group code ".$group->getCode();
}
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 .
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.
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.