I've created successfully a BE user in an own extension for TYPO3 CMS 8.7.0.
Repository Injection:
/**
* beUserRepository
*
* #var \TYPO3\CMS\Extbase\Domain\Repository\BackendUserRepository
* #inject
*/
protected $beUserRepository = null;
Part of the ActionController:
$beuser = new \TYPO3\CMS\Extbase\Domain\Model\BackendUser();
$beuser->setUserName($username);
$beuser->setEmail($email);
$beuser->setRealName($realname);
$this->beUserRepository->add($beuser);
This works fine but I can't add a password like for FE users with setPassword(). Is there any way to get there or is it restricted for security reasons to set/change a BE user password?
Create your own BackendUser model in your extension
<?php
namespace YourVendor\YourExtKey\Domain\Model;
class BackendUser extends \TYPO3\CMS\Extbase\Domain\Model\BackendUser
{
/**
* #var string
*/
protected $password = '';
/**
* Returns the password
*
* #return string
*/
public function getPassword()
{
return $this->password;
}
/**
* Sets the password
*
* #param string $password
* #return void
*/
public function setPassword($password)
{
$this->password = (string)$password;
}
}
Create your own Repository
<?php
namespace YourVendor\YourExtKey\Domain\Repository;
class BackendUserRepository extends \TYPO3\CMS\Extbase\Domain\Repository\BackendUserRepository
{
}
Then map your new domain model to be_users table:
plugin.tx_yourExtKey {
persistence {
classes {
YourVendor\YourExtKey\Domain\Model\BackendUser {
mapping {
tableName = be_users
}
}
}
}
}
Update your controller to use your new Repository
/**
* beUserRepository
*
* #var \YourVendor\YourExtKey\Domain\Repository\BackendUserRepository
* #inject
*/
protected $beUserRepository;
Back in your action
$beUser = new \YourVendor\YourExtKey\Domain\Model\BackendUser();
$saltFactory = \TYPO3\CMS\Saltedpasswords\Salt\SaltFactory::getSaltingInstance('', 'BE');
$beUser->setPassword($saltFactory->getHashedPassword($newPassword));
TYPO3\CMS\Extbase\Domain\Model\BackendUser does not have a password property, so you can not set a password without extending the model. The easiest way would be if you create an own BackendUser model in your extension that extends the TYPO3\CMS\Extbase\Domain\Model\BackendUser and configure the mapping in TS. It just needs to have the $password property with getters/setters and a repository.
Related
As I understand using repositories restricts controller from accessing database layer, and all queries goes through repository. But can controller use model (laravel can inject model instead of ID in a controller) to pass it to repository or service - for example to make a transaction between users? Or better to send IDs to repository, to find users and apply business logic (do user have money, or is he banned).
And more generic question, can you use models outside of the repository, because if you change some tables from postgres or mysql to something else your models will change also. And this means your repository should have get method to send back some DTO object?
Note: This is a general perspective on the matter, appliable to any application based on MVC, not only to Laravel.
An application based on the MVC pattern should be composed of three parts:
delivery mechanism: UI logic (user request handling and server response creation),
service layer: application logic,
domain model: business logic.
Here are some graphical representations (of my own making):
As shown above (and described in detail in the resources below), the controllers and the views are part of the delivery mechanism. They should interact with the domain model only through the service layer objects (services). Consequently, they should have no knowledge of the domain model components (entities - also known as domain objects, data mappers, repositories, etc). More of it, the controllers should have only one responsibility: to pass the values of the user request to the service layer, in order for it to update the model.
So, to answer your first question: No, controllers should not be able to create any instances of elements of the domain model (so instances of what you're calling "models" - in respect of Laravel's Active Record), or even to pass such objects to other components (like repositories, services, etc). Instead, the controllers should just pass the values of the request (the user id, for example) to the corresponding services. These services will then create the proper domain model objects and use the proper repositories, data mappers, etc, in order to save/fetch to/from database.
As for the second question (if I understood it correctly): The repositories are to be seen as collections of entities - which are domain model components. As such, elements (e.g. entity instances) can be fetched, stored, altered, or removed to/from them. So, by definition, the entities must be defined/used separately from the repositories. In regard of Laravel, the same should apply: The "models" should be defined/used separately from the repositories.
A "general" MVC implementation (for more clarity):
Controller:
<?php
namespace MyApp\UI\Web\Controller\Users;
use MyApp\Domain\Service\Users;
use Psr\Http\Message\ServerRequestInterface;
/**
* Add a user.
*/
class AddUser {
/**
* User service.
*
* #var Users
*/
private $userService;
/**
*
* #param Users $userService User service.
*/
public function __construct(Users $userService) {
$this->userService = $userService;
}
/**
* Invoke.
*
* #param ServerRequestInterface $request Request.
* #return void
*/
public function __invoke(ServerRequestInterface $request) {
// Read request values.
$username = $request->getParsedBody()['username'];
// Call the corresponding service.
$this->userService->addUser($username);
}
}
Service:
<?php
namespace MyApp\Domain\Service;
use MyApp\Domain\Model\User\User;
use MyApp\Domain\Model\User\UserCollection;
use MyApp\Domain\Service\Exception\UserExists;
/**
* Service for handling the users.
*/
class Users {
/**
* User collection (a repository).
*
* #var UserCollection
*/
private $userCollection;
/**
*
* #param UserCollection $userCollection User collection.
*/
public function __construct(UserCollection $userCollection) {
$this->userCollection = $userCollection;
}
/**
* Find a user by id.
*
* #param int $id User id.
* #return User|null User.
*/
public function findUserById(int $id) {
return $this->userCollection->findUserById($id);
}
/**
* Find all users.
*
* #return User[] User list.
*/
public function findAllUsers() {
return $this->userCollection->findAllUsers();
}
/**
* Add a user.
*
* #param string $username Username.
* #return User User.
*/
public function addUser(string $username) {
$user = $this->createUser($username);
return $this->storeUser($user);
}
/**
* Create a user.
*
* #param string $username Username.
* #return User User.
*/
private function createUser(string $username) {
$user = new User();
$user->setUsername($username);
return $user;
}
/**
* Store a user.
*
* #param User $user User.
* #return User User.
*/
private function storeUser(User $user) {
if ($this->userCollection->userExists($user)) {
throw new UserExists('Username "' . $user->getUsername() . '" already used');
}
return $this->userCollection->storeUser($user);
}
}
Repository:
<?php
namespace MyApp\Domain\Infrastructure\Repository\User;
use MyApp\Domain\Model\User\User;
use MyApp\Domain\Infrastructure\Mapper\User\UserMapper;
use MyApp\Domain\Model\User\UserCollection as UserCollectionInterface;
/**
* User collection.
*/
class UserCollection implements UserCollectionInterface {
/**
* User mapper (a data mapper).
*
* #var UserMapper
*/
private $userMapper;
/**
*
* #param UserMapper $userMapper User mapper.
*/
public function __construct(UserMapper $userMapper) {
$this->userMapper = $userMapper;
}
/**
* Find a user by id.
*
* #param int $id User id.
* #return User|null User.
*/
public function findUserById(int $id) {
return $this->userMapper->fetchUserById($id);
}
/**
* Find all users.
*
* #return User[] User list.
*/
public function findAllUsers() {
return $this->userMapper->fetchAllUsers();
}
/**
* Store a user.
*
* #param User $user User.
* #return User User.
*/
public function storeUser(User $user) {
return $this->userMapper->saveUser($user);
}
/**
* Check if the given user exists.
*
* #param User $user User.
* #return bool True if user exists, false otherwise.
*/
public function userExists(User $user) {
return $this->userMapper->userExists($user);
}
}
Entity:
<?php
namespace MyApp\Domain\Model\User;
/**
* User.
*/
class User {
/**
* Id.
*
* #var int
*/
private $id;
/**
* Username.
*
* #var string
*/
private $username;
/**
* Get id.
*
* #return int
*/
public function getId() {
return $this->id;
}
/**
* Set id.
*
* #param int $id Id.
* #return $this
*/
public function setId(int $id) {
$this->id = $id;
return $this;
}
/**
* Get username.
*
* #return string
*/
public function getUsername() {
return $this->username;
}
/**
* Set username.
*
* #param string $username Username.
* #return $this
*/
public function setUsername(string $username) {
$this->username = $username;
return $this;
}
}
Data mapper:
<?php
namespace MyApp\Domain\Infrastructure\Mapper\User;
use PDO;
use MyApp\Domain\Model\User\User;
use MyApp\Domain\Infrastructure\Mapper\User\UserMapper;
/**
* PDO user mapper.
*/
class PdoUserMapper implements UserMapper {
/**
* Database connection.
*
* #var PDO
*/
private $connection;
/**
*
* #param PDO $connection Database connection.
*/
public function __construct(PDO $connection) {
$this->connection = $connection;
}
/**
* Fetch a user by id.
*
* Note: PDOStatement::fetch returns FALSE if no record is found.
*
* #param int $id User id.
* #return User|null User.
*/
public function fetchUserById(int $id) {
$sql = 'SELECT * FROM users WHERE id = :id LIMIT 1';
$statement = $this->connection->prepare($sql);
$statement->execute([
'id' => $id,
]);
$data = $statement->fetch(PDO::FETCH_ASSOC);
return ($data === false) ? null : $this->convertDataToUser($data);
}
/**
* Fetch all users.
*
* #return User[] User list.
*/
public function fetchAllUsers() {
$sql = 'SELECT * FROM users';
$statement = $this->connection->prepare($sql);
$statement->execute();
$data = $statement->fetchAll(PDO::FETCH_ASSOC);
return $this->convertDataToUserList($data);
}
/**
* Check if a user exists.
*
* Note: PDOStatement::fetch returns FALSE if no record is found.
*
* #param User $user User.
* #return bool True if the user exists, false otherwise.
*/
public function userExists(User $user) {
$sql = 'SELECT COUNT(*) as cnt FROM users WHERE username = :username';
$statement = $this->connection->prepare($sql);
$statement->execute([
':username' => $user->getUsername(),
]);
$data = $statement->fetch(PDO::FETCH_ASSOC);
return ($data['cnt'] > 0) ? true : false;
}
/**
* Save a user.
*
* #param User $user User.
* #return User User.
*/
public function saveUser(User $user) {
return $this->insertUser($user);
}
/**
* Insert a user.
*
* #param User $user User.
* #return User User.
*/
private function insertUser(User $user) {
$sql = 'INSERT INTO users (username) VALUES (:username)';
$statement = $this->connection->prepare($sql);
$statement->execute([
':username' => $user->getUsername(),
]);
$user->setId($this->connection->lastInsertId());
return $user;
}
/**
* Update a user.
*
* #param User $user User.
* #return User User.
*/
private function updateUser(User $user) {
$sql = 'UPDATE users SET username = :username WHERE id = :id';
$statement = $this->connection->prepare($sql);
$statement->execute([
':username' => $user->getUsername(),
':id' => $user->getId(),
]);
return $user;
}
/**
* Convert the given data to a user.
*
* #param array $data Data.
* #return User User.
*/
private function convertDataToUser(array $data) {
$user = new User();
$user
->setId($data['id'])
->setUsername($data['username'])
;
return $user;
}
/**
* Convert the given data to a list of users.
*
* #param array $data Data.
* #return User[] User list.
*/
private function convertDataToUserList(array $data) {
$userList = [];
foreach ($data as $item) {
$userList[] = $this->convertDataToUser($item);
}
return $userList;
}
}
View:
<?php
namespace MyApp\UI\Web\View\Users;
use MyApp\UI\Web\View\View;
use MyApp\Domain\Service\Users;
use MyLib\Template\TemplateInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ResponseFactoryInterface;
/**
* Add a user.
*/
class AddUser extends View {
/**
* User service.
*
* #var Users
*/
private $userService;
/**
*
* #param ResponseFactoryInterface $responseFactory Response factory.
* #param TemplateInterface $template Template.
* #param Users $userService User service.
*/
public function __construct(ResponseFactoryInterface $responseFactory, TemplateInterface $template, Users $userService) {
parent::__construct($responseFactory, $template);
$this->userService = $userService;
}
/**
* Display a form for adding a user.
*
* #return ResponseInterface Response.
*/
public function index() {
$body = $this->template->render('#Template/Users/add-user.html.twig', [
'activeMainMenuItem' => 'addUser',
'action' => '',
]);
$response = $this->responseFactory->createResponse();
$response->getBody()->write($body);
return $response;
}
/**
* Add a user.
*
* #return ResponseInterface Response.
*/
public function addUser() {
$body = $this->template->render('#Template/Users/add-user.html.twig', [
'activeMainMenuItem' => 'addUser',
'message' => 'User successfully added.',
]);
$response = $this->responseFactory->createResponse();
$response->getBody()->write($body);
return $response;
}
}
Resources:
How should a model be structured in MVC?
Keynote: Architecture the Lost Years
GeeCON 2014: Sandro Mancuso - Crafted Design
This is an opiniated answer but here's my take. What I suggest is to not add a repository layer for the sake of having a repository in Laravel. whatever methods you need, add them to the model classes, When they are bloated/expect it to be bloated then only think about repositories (Most probably you would need a service class or some other abstraction here).
Since all these eloquent model classes can be resolved from container its easy to use them. it's accessible anywhere and even in the controller like you have mentioned can be injected which provides a great level of ease.
And repositories help to change for example the underlying database, But eloquent provides us with that flexibility already. And when you plan to change your database, I don't think its going to be a simple change so why wrap the logic up in another layer of abstraction (unneccessarily).
At least from my experience the repository pattern doesn't suite well with Active Record Pattern. Which Laravel follows. Where repository suites very well for data mapper pattern (for example Symfony uses it). Thats why in laravel documentation you don't see them embracing the repository pattern. Rather in symfony documentation you can see it.
So I suggest to embrace the framework than to fight it
I have the following phpunit test for testing the controllers:
The DefaultControllerTest:
namespace Tests\AppBundle\Controller;
use Tests\AppBundle\Controller\BasicHttpController;
use AppBundle\DataFixtures\Test\DummyUserFixtures;
/**
* #testtype Functional
*/
class DefaultControllerTest extends BasicHttpController
{
/**
* {#inheritdoc}
*/
public function setUp()
{
$fixture = new DummyUserFixtures();
$fixture->load($this->entityManager);
}
/**
* Testing the Behavior when visiting the index page
*/
public function testIndex()
{
$client = $this->client;
$router=$client->getContainer()->get('router');
$crawler = $client->request('GET', '/');
$response=$client->getResponse();
$this->assertTrue($client->getResponse()->isRedirect());
$this->assertEquals($router->getRouteCollection()->get('fos_user_security_login')->getPath(),$response->headers->get('Location'));
//#todo Create Dummy Users
// $this->checkPanelAfterSucessfullLogin($crawler);
}
}
That extends the following test BasicHttpController (try to apply the DRY principle):
namespace Tests\AppBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
use Doctrine\Common\DataFixtures\Purger\ORMPurger;
class BasicHttpController extends WebTestCase
{
protected $entityManager=null;
protected $client=null;
/**
* {#inheritdoc}
*/
public function __construct()
{
parent::__construct();
$this->client = static::createClient();
$container = $this->client->getContainer();
$doctrine = $container->get('doctrine');
$this->entityManager=$doctrine->getManager();
}
/**
* Remove all entities from the database
*/
protected function truncateEntities()
{
$purger = new ORMPurger($this->entityManager());
$purger->purge();
}
/**
* {#inheritdoc}
*/
public function tearDown()
{
$this->truncateEntities();
}
/**
* #param username String the user's username
* #param passwoρd String the user's password
*/
protected function checkPanelAfterSucessfullLogin($crawler,string $username,string $password)
{
//Submitting the form
$form=$crawler->selectButton('_submit')->form();
$form['_username']=$username;
$form['_password']=$password;
$crawler=$crawler->submit($form);
$response=$client->getResponse();
$this->assertTrue($client->getResponse()->isRedirect());
$client->followRedirect();
//Checking header
$headerDom=$crawler->filter('header')->childen()->filter('nav.navbar')->children();
$this->assertCount(1,$headerDom->find('a.navbar-brand')); //homepage link
$this->assertCount(1,$headerDom->find('a.btn-danger')); //Logout button
}
}
As you can see I try to load the following fixture:
namespace AppBundle\DataFixtures\Test;
use Doctrine\Common\DataFixtures\AbstractFixture;
use Doctrine\Common\DataFixtures\OrderedFixtureInterface;
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Doctrine\Common\Persistence\ObjectManager;
class DummyUserFixtures extends AbstractFixture implements OrderedFixtureInterface,ContainerAwareInterface
{
/**
* #var ContainerInterface
*/
private $container=null;
/**
* {#inheritDoc}
*/
public function setContainer(ContainerInterface $container = null)
{
$this->container = $container;
}
/**
* Generic function that creates a user with provided information.
* #param $name {String} The user's name
* #param $surname {String} The user's surname
* #param $username {String} The user's username
* #param $password {String} The user's password
* #param $email {String} The user's recovery email
* #param $role {String} The user's system role
* #param $phone {String | null} The user's phone number
* #param $organization {String|null} The user's organization
* #param $occupation {String|null} The user's occupation
*
* #return AppBundle\Entity\User
*/
private function createUser($name,$surname,$username,$password,$email,$role,$phone=null,$organization=null,$occupation=null)
{
$fosUserManager=$this->container->get('fos_user.user_manager');
/**
* #var AppBundle\Entity\User
*/
$user=$fosUserManager->createUser();
$user->setUsername($username);
$user->setEmail($email);
$user->setPlainPassword($password);
$user->setEnabled(true);
$user->setRoles(array($role));
$user->setName($name);
$user->setSurname($surname);
if($phone){
$user->setPhone($phone);
}
if($organization){
$user->setOrganization($organization);
}
if($occupation){
$user->setOccupation($occupation);
}
$fosUserManager->updateUser($user, true);
return $user;
}
/**
* {#inheritDoc}
*/
public function load(ObjectManager $manager)
{
$this->createUser('John','Doe','jdoe','simplepasswd','jdoe#example.com','ROLE_USER','+3021456742324','Acme Products','Soft Engineer');
$this->createUser('Jackie','Chan','jchan','thesimplepasswd','jackiechan#example.com','ROLE_ADMIN','+302141232324','Holywood','Actor');
$this->createUser('Chuck','Norris','chuck_norris','unhackablepasswd','chucknorris#example.com','ROLE_SUPERADMIN',null,'Universe','Master');
}
public function getOrder()
{
return 1;
}
}
But for some reason I get the following error:
There was 1 error:
1) Tests\AppBundle\Controller\DefaultControllerTest::testIndex
Error: Call to a member function get() on null
/home/vagrant/code/src/AppBundle/DataFixtures/Test/DummyUserFixtures.php:50
/home/vagrant/code/src/AppBundle/DataFixtures/Test/DummyUserFixtures.php:87
/home/vagrant/code/tests/AppBundle/Controller/DefaultControllerTest.php:19
Further debugging has proved that the error is triggered by the following line in DummyUserFixtures:
$fosUserManager=$this->container->get('fos_user.user_manager');
So do you know how to load the data via fixtures?
In order to get it working you should set the service container you generate from the static::createClient() method and pass it via the $fixture->setContainer($container)
So a good approach is to define the container as protected instance variable to the BasicHttpController so any Test class (eg. the DefaultControllerTest in your case) is able to load the fixtures accordingly.
So using the setUp method and instance variables of BasicHttpController should be the following:
//Namespace declaration goes there
class BasicHttpController extends WebTestCase
{
protected $entityManager=null;
protected $client=null;
protected $container=null;
/**
* {#inheritdoc}
*/
public function setUp()
{
$this->client = static::createClient();
$this->container = $this->client->getContainer();
$doctrine = $this->container->get('doctrine');
$this->entityManager=$doctrine->getManager();
}
// Rest methods here
}
Note: on classes that are getting inherited from BasicHttpController you can define the setUp like that:
public function setUp()
{
parent::setUp();
// Add extra stuff here
}
So you can do more setUp bootstrapping before tests.
I try to build a custom registration form which should be displayed in a custom block and I don't want to insert the normal registration form and alter it via a hook or use an extension like form_block, because I want to learn the ways how drupal 8 works with forms.
My block looks like this:
<?php
namespace Drupal\ajax_registration_form\Plugin\Block;
use Drupal\ajax_registration_form\Form\AjaxRegistrationForm;
use Drupal\Core\Block\BlockBase;
/**
* Provides a 'AjaxRegistrationBlock' block.
*
* #Block(
* id = "ajax_registration_block",
* admin_label = #Translation("Ajax registration block"),
* )
*/
class AjaxRegistrationBlock extends BlockBase {
/**
* {#inheritdoc}
*/
public function build() {
$content = \Drupal::formBuilder()->getForm(AjaxRegistrationForm::class);
return $content;
}
}
My custom registration form looks like this:
<?php
namespace Drupal\ajax_registration_form\Form;
use Drupal\Core\Form\FormStateInterface;
use Drupal\user\RegisterForm;
class AjaxRegistrationForm extends RegisterForm {
/**
* {#inheritdoc}
*/
public function form(array $form, FormStateInterface $form_state) {
return parent::form($form, $form_state);
}
}
I just tried to extend the normal RegisterForm and in the first step I just wanted to return the parent form to see if it works. But it doesn't...
Error message:
Fatal error: Call to a member function getEntityTypeId() on null in /Users/*******/Sites/priv/radweiser/web/core/lib/Drupal/Core/Entity/EntityForm.php on line 77
I think it's the missing user entity in the form, but I don't know how I can "put" this entity in my form.
I found the solution in the code of the formblock module.
I altered my block to something like this:
<?php
namespace Drupal\ajax_registration_form\Plugin\Block;
use Drupal\Core\Annotation\Translation;
use Drupal\Core\Block\Annotation\Block;
use Drupal\Core\Block\BlockBase;
use Drupal\Core\Entity\EntityFormBuilderInterface;
use Drupal\Core\Entity\EntityManagerInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\Session\AccountInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Provides a 'AjaxRegistrationBlock' block.
*
* #Block(
* id = "ajax_registration_block",
* admin_label = #Translation("Ajax registration block"),
* )
*/
class AjaxRegistrationBlock extends BlockBase implements ContainerFactoryPluginInterface {
/**
* The entity manager
*
* #var \Drupal\Core\Entity\EntityManagerInterface.
*/
protected $entityManager;
/**
* The entity form builder
*
* #var \Drupal\Core\Entity\EntityManagerInterface.
*/
protected $entityFormBuilder;
/**
* Constructs a new UserRegisterBlock plugin
*
* #param array $configuration
* A configuration array containing information about the plugin instance.
* #param string $plugin_id
* The plugin_id for the plugin instance.
* #param mixed $plugin_definition
* The plugin implementation definition.
* #param \Drupal\Core\Entity\EntityManagerInterface $entityManager
* The entity manager.
* #param \Drupal\Core\Entity\EntityFormBuilderInterface $entityFormBuilder
* The entity form builder.
*/
public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityManagerInterface $entityManager, EntityFormBuilderInterface $entityFormBuilder) {
parent::__construct($configuration, $plugin_id, $plugin_definition);
$this->entityManager = $entityManager;
$this->entityFormBuilder = $entityFormBuilder;
}
/**
* #inheritdoc
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
return new static(
$configuration,
$plugin_id,
$plugin_definition,
$container->get('entity.manager'),
$container->get('entity.form_builder')
);
}
/**
* Implements \Drupal\block\BlockBase::build().
*/
public function build() {
$build = array();
$account = $this->entityManager->getStorage('user') ->create(array());
$build['form'] = $this->entityFormBuilder->getForm($account, 'register');
$build['form']['account']['mail']['#description'] = t('');
kint($build['form']['account']);
return $build;
}
/**
*Implements \Drupal\block\BlockBase::blockAccess().
*
* #param \Drupal\Core\Session\AccountInterface $account
*
* #return bool|\Drupal\Core\Access\AccessResult
*/
public function blockAccess(AccountInterface $account) {
return ($account->isAnonymous()) && (\Drupal::config('user.settings')->get('register') != USER_REGISTER_ADMINISTRATORS_ONLY);
}
}
Now I can alter the form and implement ajax logic using the Form Api (alter the mail input description as example)
I have placed this block in front page content but it is not visible
<span data-big-pipe-placeholder-id="callback=Drupal%5Cblock%5CBlockViewBuilder%3A%3AlazyBuilder&args%5B0%5D=userregistrationform&args%5B1%5D=full&args%5B2%5D&token=-MyZMBSv_tseO1_TExVECdGUQnyGrlvE9eST64je7Ho"></span>
it shows like this
FYI I have changed permissions to isAnonymous()
The default model "User" in laravel throws error when I tried to use it. What I tried is,
$user = new User();
$user->email = Input::get('email');
$user->password = Hash::make(Input::get('password'));
$user->name = "Blah Blah";
$user->access_type = "admin";
$user->access_status = 1;
$user->save();
and the error thrown is
Symfony \ Component \ Debug \ Exception \ FatalErrorException
Call to undefined method User::save()
What is the issue? I also tried User::all() to retrieve the values, which also throws error Call to undefined method User::all().
Update1:
Here is my model
use Illuminate\Auth\UserInterface;
use Illuminate\Auth\Reminders\RemindableInterface;
class User extends Eloquent implements UserInterface, RemindableInterface {
/**
* The database table used by the model.
*
* #var string
*/
protected $table = 'users';
/**
* The attributes excluded from the model's JSON form.
*
* #var array
*/
protected $hidden = array('password');
/**
* Get the unique identifier for the user.
*
* #return mixed
*/
public function getAuthIdentifier()
{
return $this->getKey();
}
/**
* Get the password for the user.
*
* #return string
*/
public function getAuthPassword()
{
return $this->password;
}
/**
* Get the token value for the "remember me" session.
*
* #return string
*/
public function getRememberToken()
{
return $this->remember_token;
}
/**
* Set the token value for the "remember me" session.
*
* #param string $value
* #return void
*/
public function setRememberToken($value)
{
$this->remember_token = $value;
}
/**
* Get the column name for the "remember me" token.
*
* #return string
*/
public function getRememberTokenName()
{
return 'remember_token';
}
/**
* Get the e-mail address where password reminders are sent.
*
* #return string
*/
public function getReminderEmail()
{
return $this->email;
}
}
Update2:
I tried writing another model names and class name as Users, which works perfectly. But for authentication, it must be the User table right?
The reason for the issue is autoloader load wrong "User" model. Please have a look at the "/vendor/composer/autoload_classmap.php" file. Inside the return array value for the key "User" must be $baseDir . '/app/models/User.php
return array(
...,
'User' => $baseDir . '/app/models/User.php',
...,
);
Maybe User is a reserved word, just give the model another name say UserTbl
Still didn't received any answer to my question. Anyways now I'm running it using the new model named Users with the same doubt in mind.
I am using Netbeans 8 for a Symfony2 project.
I have created a factory class for my model queries (they are static calls and mess up testing).
E.g
<?php
namespace My\Custom\Bundle\Classes\Factories;
use My\Custom\Bundle\Model\UserQuery;
class QueryFactory
{
/**
* Class name
* #access public
*/
const CLASS_NAME = __CLASS__;
/**
* newUserQuery()
*
* Creates a new user query object.
* #access public
* #return My\Custom\Bundle\Model\UserQuery
*/
public function newUserQuery()
{
return UserQuery::create();
}
}
What I want is for the auto complete to work on a variable that is created from a factory method (in this case the Propel methods for the User query).
<?php
namespace My\Custom\Bundle\Controller;
use My\Custom\Bundle\Classes\Factories\QueryFactory;
class ReportingController
{
private $queryFactory;
public function __construct(QueryFactory $query_factory)
{
$this->queryFactory = $query_factory;
}
public function fubar()
{
$user = $this->queryFactory->newUserQuery();
// now want auto complete on the $user (in this case the propel methods)
// $user->filterById(1);
}
}
Any ideas?
I think the problem is #return pointing to My\Custom\Bundle\Classes\Factories\My\Custom\Bundle\Model\UserQuery
try changing it to this
/**
* ...
* #return UserQuery
*/
Without the use statement it should be like this
/**
* ...
* #return \My\Custom\Bundle\Model\UserQuery
*/