Call to a member function store() on null on Livewire - laravel-livewire

I'm new to Livewire and I faced this problem Call to a member function store() on null I don't know how to make the store() function not work when I don't send a file! graduation_certificate it is nullable.
Database file
public function up()
{
Schema::create('user_trainees', function(Blueprint $table) {
$table->increments('id');
$table->integer('user_id')->unsigned();
$table->integer('region_id')->unsigned();
$table->integer('city_id')->unsigned();
$table->integer('university_id')->unsigned();
$table->integer('department_id')->unsigned();
$table->string('major', 150);
$table->bigInteger('student_number')->nullable();
$table->float('gpa');
$table->enum('gpa_type', array('4', '5'));
$table->enum('training_date', array('firstsemester', 'secondsemester', 'thirdsemester', 'summersemester'))->nullable();
$table->integer('training_hours')->nullable();
$table->integer('graduation_year')->nullable();
$table->enum('academic_degree', array('bachelor', 'diploma'));
$table->string('graduation_certificate', 200)->nullable();
$table->string('academic_transaction', 200);
$table->string('cv', 200);
$table->tinyInteger('is_graduate');
$table->timestamps();
$table->softDeletes();
});
}
blade file
<x-form.label label="وثيقة التخرج" name="graduation_certificate" />
<div class="flex">
<input type="file" wire:model="graduation_certificate" name="graduation_certificate"
id="graduation_certificate"
class="px-8 py-12 border-2 border-dashed rounded-md dark:border-gray-700 dark:text-gray-400 dark:bg-gray-800">
</div>
livewire class
public function submit()
{
$user_uni = User::create([
'name' => "{$this->firstName} {$this->lastName}",
'type_id' => $this->userType,
'email' => $this->email,
'password' => bcrypt($this->password),
'gender' => $this->gender,
'mobile' => $this->mobile,
'is_active' => 1,
]);
UserTrainee::create([
'user_id' => $user_uni->id,
'region_id' => $this->region,
'city_id' => $this->city,
'university_id' => $this->university,
'department_id' => $this->department,
'major' => $this->major,
'student_number' => $this->studentNumber,
'gpa' => $this->gpa,
'gpa_type' => $this->gpa_type,
'training_date' => $this->training_date,
'training_hours' => $this->trainingHours,
'graduation_year' => $this->graduation_year,
'academic_degree' => $this->academic_degree,
'graduation_certificate' => $this->graduation_certificate->store('files', 'public'),
'academic_transaction' => $this->academic_transaction->store('files', 'public'),
'cv' => $this->cv->store('files', 'public'),
'is_graduate' => $this->traineeType,
]);
}

You don't conditionally store the files, meaning that even if you haven't uploaded something (meaning its NULL), you attempt to store it. Just wrap some conditions around it,
// ...
'graduation_certificate' => $this->graduation_certificate ? $this->graduation_certificate->store('files', 'public') : null,
'academic_transaction' => $this->academic_transaction ? $this->academic_transaction->store('files', 'public') : null,
'cv' => $this->cv ? $this->cv->store('files', 'public') : null,
// ...

you have to make variable of cv like you made for graduation_certificate, cv is getting NULL that's why you are facing this error

Related

Set values for default address fields in Drupal 8

I need to set values for default address fields(langcode, country_code, administrative_area, address_locality ect.) when I create a node. I used below code in the submitForm function of a Form class which is extends by Drupal\Core\Form\FormBase class. But it not works for me.
$venueNode = Node::create([
'type' => 'venue',
'title' => 'Venue',
'field_address' => [
'country_code' => 'US',
'address_line1' => '1098 Alta Ave',
'locality' => 'Mountain View',
'administrative_area' => 'US-CA',
'postal_code' => '94043',
],
]);
$venueNode->save();
I made a mistake here. There should be a 0 index for field_address. Therefore the code should be like below.
$venueNode = Node::create([
'type' => 'venue',
'title' => 'Venue',
'field_address' => [
0 => [
'country_code' => 'US',
'address_line1' => '1098 Alta Ave',
'locality' => 'Mountain View',
'administrative_area' => 'US-CA',
'postal_code' => '94043',
],
],
]);
$venueNode->save();

Zf2 form fieldset returns no fields

I have done bunch of projects using ZF2 and Doctrine2. I build my form with as it follows: Create Form class extending Form, then create Fieldsets and set it as a base fieldset, then in the fieldset I add my fields. Within module.php I create factories in formElementConfig for my forms. It was working allways this way until now. I created a new project and suddenly I encounter a problem which I cant find what is going on. This is my code
//module.php
public function getFormElementConfig()
{
return array(
'factories' => array(
'OfferForm' => function($sm) {
$locator = $sm->getServiceLocator();
$form = new \Application\Form\OfferForm();
$form->setServiceLocator($locator);
return $form;
},
)
);
}
//Form
class OfferForm extends Form implements ServiceLocatorAwareInterface
{
protected $serviceLocator;
public function init()
{
$this->setAttributes(array(
'id' => 'offer',
'method' => 'post',
'class' => 'custom',
'enctype' => 'multipart/form-data'
));
$this->setAttribute('method', 'post')
->setHydrator(new ClassMethodsHydrator(false))
->setInputFilter(new InputFilter());
$this->add(array(
'name' => 'offer',
'type' => 'Application\Form\Fieldset\OfferFieldset',
'options' => array(
'use_as_base_fieldset' => true
)
));
$this->add(array(
'type' => 'Zend\Form\Element\Csrf',
'name' => 'csrf'
));
$this->add(array(
'name' => 'submit',
'attributes' => array(
'id' => 'submit',
'type' => 'submit',
'value' => $this->getServiceLocator()->getServiceLocator()->get('translator')->translate('Submit offer'),
'class' => 'btn btn-info'
)
));
}
....
//Fieldset
class OfferFieldset extends Fieldset implements InputFilterProviderInterface, ServiceLocatorAwareInterface
{
public function init()
{
$this->setHydrator(new ClassMethodsHydrator(false))
->setObject(new Offer());
$this->add(array(
'name' => 'title',
'type' => 'Zend\Form\Element\Text',
'attributes' => array(
'required' => 'required',
'class' => 'form-control',
)
));
....other fileds
}
/**
* #return array
*/
public function getInputFilterSpecification()
{
....
}
}
//Controller
$em = $this->getObjectManager();
$offer = new Offer();
$form = $this->getServiceLocator()->get('FormElementManager')->get('OfferForm');
$form->setHydrator(new DoctrineHydrator($em, 'Application\Entity\Offer'))->bind($offer);
if ($this->request->isPost()) {
$form->setData($this->request->getPost());
if ($form->isValid()) {
var_dump('ok');
}
}
$form->prepare();
return new ViewModel(array(
'form' => $form,
));
This way of doing things is allways working for me until now. If I try to get form element in the Veiw with $this->form->get('offer')->get('title') it says there is no field with name 'title'
One thing that i noticed is when form is called in the controller ($form = $this->getServiceLocator()->get('FormElementManager')->get('OfferForm');) the fieldset method init() where all my fields are set is not invoked.
I tried to dump data there and to die() the application but it did not get in to the method at all.
I can provide more code but I think this is all about building the form
You also need to add your fieldset to the formelementmanager configuration. The manager's initializer will call your fieldset init() method.

SF2: How to custom the form type messages?

I want to know how I can modify the error message on my ContactType.
It's possible directly in the Type ?
My current code:
class ContactType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
//...
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$collectionConstraint = new Collection(array(
'name' => array(
new NotBlank(array('message' => 'My custon message.')),
new Length(array('min' => 2), array('message' => 'My custon message.'))
),
'email' => array(
new NotBlank(array('message' => 'My custon message.')),
new Email(array('message' => 'My custon message.'))
),
'subject' => array(
new NotBlank(array('message' => 'My custon message.')),
new Length(array('min' => 10), array('message' => 'My custon message.'))
),
'message' => array(
new NotBlank(array('message' => 'My custon message')),
new Length(array('min' => 5))
)
));
$resolver->setDefaults(array(
'constraints' => $collectionConstraint
));
}
public function getName()
{
return 'contact';
}
}
Thanks you all for your helping.
Best regards,
It's recommend to change the message of the assertion instead, but you can also use the invalid_message setting of a form type.

Unit Testing OAuth Login with Cake 2.3

I need some advice on how to set up a unit test in Cake 2.3 that tests OAuth login. I'm using the thomseddon/cakephp-oauth-server plugin. Note: I've reviewed examples such as CakePHP 2.3 - Unit testing User Login, but I'm still confused about how exactly to approach an OAuth test using the plugin. Any help appreciated.
The following is what I currently have in my unit test. Not very much of a test, yet.
/**
* testOAuthLogin method
* Tests that OAuth login works
* #return void
*/
public function testOAuthLogin(){
$data = array(
'response_type' => 'code',
'client_id' => getenv('THREE_SCALE_APP_ID'),
'User' => array(
'username' => TEST_USERNAME,
'passwd' => TEST_PASSWORD
)
);
$result = $this->testAction('/oauth/login', array(
'data' => $data,
'method' => 'post'
));
debug($result);
}
This returns:
{"error":"invalid_client","error_description":"No client id supplied"}
I was able to figure this out. I just needed to setup up proper fixtures for User and AccessToken. And then I had to ensure that these were imported in the controller that I was testing in via $fixtures.
Example of my AccessTokenFixture:
<?php
App::uses('OAuthComponent', 'OAuth.Controller/Component');
/**
* AccessTokenFixture
*
*/
class AccessTokenFixture extends CakeTestFixture {
/**
* Fields
*
* #var array
*/
public $fields = array(
'oauth_token' => array('type' => 'string', 'null' => false, 'default' => null, 'length' => 40, 'key' => 'primary', 'collate' => 'utf8_general_ci', 'charset' => 'utf8'),
'client_id' => array('type' => 'string', 'null' => false, 'default' => null, 'length' => 36, 'collate' => 'utf8_general_ci', 'charset' => 'utf8'),
'user_id' => array('type' => 'integer', 'null' => false, 'default' => null),
'expires' => array('type' => 'integer', 'null' => false, 'default' => null),
'scope' => array('type' => 'string', 'null' => true, 'default' => null, 'collate' => 'utf8_general_ci', 'charset' => 'utf8'),
'indexes' => array(
'PRIMARY' => array('column' => 'oauth_token', 'unique' => 1)
),
'tableParameters' => array('charset' => 'utf8', 'collate' => 'utf8_general_ci', 'engine' => 'MyISAM')
);
/**
* init method
* #return void
*/
public function init() {
$this->records = array(
array(
'oauth_token' => OAuthComponent::hash('SAMPLE_ACCESS_TOKEN'),
'client_id' => 'YOUR_CLIENT_ID',
'user_id' => 1,
'expires' => 1367263611232323,
'scope' => ''
),
array(
'oauth_token' => OAuthComponent::hash('SAMPLE_ACCESS_TOKEN'),
'client_id' => 'YOUR_CLIENT_ID',
'user_id' => 2,
'expires' => 13672640632323323,
'scope' => ''
)
);
parent::init();
}
}

CakePHP2 testing login()

I want to test the login() action in my UsersController.php
<?php
class UsersController extends AppController {
public $helpers = array('Html', 'Form');
public $components = array('RequestHandler');
public function beforeFilter() {
parent::beforeFilter();
$this->Auth->allow('logout', 'login');
// $this->Auth->allow('logout');
$this->Security->csrfExpires = '+1 hour';
}
public function login() {
if($this->request->is('post')) {
if ($this->Auth->login()) {
return $this->redirect($this->Auth->redirect());
} else {
$this->Session->setFlash(__('Invalid username or password, try again'),'info');
}
}
}
The AppController.php
<?php
App::uses('Controller', 'Controller');
class AppController extends Controller {
public $components = array(
'Session',
'Security',
'Auth' => array(
'loginRedirect' => array('controller' => 'dashboards', 'action' => 'index'),
'logoutRedirect' => array('controller' => 'dashboards', 'action' => 'welcome'),
'authorize' => array('Controller')
)
);
public function isAuthorized($user) {
//Admin can access every action
if (isset($user['role']) && $user['role'] === 'admin') {
return true;
}
//Default deny
$this->Session->setFlash('You are not allowed to access the requested page');
return false;
}
}
The UsersControllerTest.php
<?php
class UsersControllerTest extends ControllerTestCase {
public $autoRender = false;
public $fixtures = array('app.user','app.account');
public function setUp() {
parent::setUp();
$this->User = ClassRegistry::init('User');
}
...snip...
public function testLogin() {
$this->Users = $this->generate('Users', array(
'components' => array(
//'Session',
'Security' => array('_validatePost'),
)
));
$this->Users->Security->expects($this->any())
->method('_validatePost')
->will($this->returnValue(true));
$user = array();
$user['User']['username'] = 'admin';
//$user['User']['password'] = Security::hash('test', null, true);
$user['User']['password'] = 'test';
$result = $this->testAction('/users/login',
array('data' => $user, 'method' => 'post', 'return' => 'contents')
);
debug( $this->contents);
//OUTPUTS: I get "Invalid username or password, try again"
//EXPECTED: A successful login message since I provided the correct credentials
}
So, how would I test my login() method when the $this->testAction('/users/login', array('data' => $user, 'method' => 'post', 'return' => 'contents')); returns nothing?
OUTPUTS: I get "Invalid username or password, try again"
EXPECTED: A successful login message since I provided the correct credentials
Any reply would be greatly appreciated. Thanks!
Thanks to #jeremyharris I was able to test my login()
UsersControllerTest.php
public function testLogin() {
$this->Users = $this->generate('Users', array(
'components' => array(
'Security' => array('_validatePost'),
)
));
$data = array();
$data['User']['username'] = 'admin';
$data['User']['password'] = 'test';
$this->Users->Auth->logout();
$this->testAction('/users/login',
array('data' => $data, 'method' => 'post', 'return' => 'contents')
);
$result = $this->testAction('/',
array('method' => 'get', 'return' => 'contents')
);
// debug($result);
$this->assertContains('You are logged in as: <span class="label">admin</span>',$result);
}
public function testLoginInvalid() {
$this->Users = $this->generate('Users', array(
'components' => array(
'Security' => array('_validatePost'),
)
));
$data = array();
$data['User']['username'] = 'admin';
$data['User']['password'] = 'BLAH!';
$this->Users->Auth->logout();
$this->testAction('/users/login',
array('data' => $data, 'method' => 'post', 'return' => 'contents')
);
$result = $this->testAction('/users/login',
array('method' => 'get', 'return' => 'contents')
);
// debug($result);
$this->assertNotContains('You are logged in as',$result);
$this->assertContains('id="UserLoginForm" method="post"',$result);
}
UserFixture.php, I used the init() method - as #jeremyharris said regarding the hashed passwords.
<?php
App::uses('AuthComponent', 'Controller/Component');
class UserFixture extends CakeTestFixture {
/* Optional. Set this property to load fixtures to a different test datasource */
public $useDbConfig = 'test';
public $fields = array(
'id' => array('type' => 'integer', 'key' => 'primary'),
'account_id' => array('type' => 'integer'),
'username' => array('type' => 'string', 'length' => 255, 'null' => false),
'email' => array('type' => 'string', 'length' => 255, 'null' => false),
'password' => array('type' => 'string', 'length' => 255, 'null' => false),
'password_token' => array('type' => 'string', 'length' => 255, 'null' => false),
'password_token_expiry' => array('type' => 'string', 'length' => 255, 'null' => false),
'role' => array('type' => 'string', 'length' => 25, 'null' => false),
'created' => 'datetime',
'modified' => 'datetime'
);
/* public $records = array(
array('id'=>1, 'account_id' => 1, 'username' => 'admin', 'email' => 'admin#test.com', 'password' => 'f57f702f8d557ae5318fa49455cbe9838c1d1712', 'role' => 'admin', 'password_token'=>'', 'password_token_expiry'=>'','created' => '2012-03-18 10:39:23', 'modified' => '2012-03-18 10:41:31'),
array('id'=>2, 'account_id' => 1, 'username' => 'user', 'email' => 'user#test.com', 'password' => 'f57f702f8d557ae5318fa49455cbe9838c1d1712', 'role' => 'user', 'password_token'=>'', 'password_token_expiry'=>'', 'created' => '2012-03-18 10:39:23', 'modified' => '2012-03-18 10:41:31')
);
*/
public function init() {
$this->records = array(
array('id'=>1, 'account_id' => 1, 'username' => 'admin', 'email' => 'admin#test.com', 'password' => AuthComponent::password('test'), 'role' => 'admin', 'password_token'=>'', 'password_token_expiry'=>'','created' => '2012-03-18 10:39:23', 'modified' => '2012-03-18 10:41:31'),
array('id'=>2, 'account_id' => 1, 'username' => 'user', 'email' => 'user#test.com', 'password' => AuthComponent::password('test'), 'role' => 'user', 'password_token'=>'', 'password_token_expiry'=>'','created' => '2012-03-18 10:39:23', 'modified' => '2012-03-18 10:41:31'),
);
parent::init();
}
}
The first testAction() is a POST, then the second one gets the "next" page - from there I do the asserts.
The problem is that you are mocking the entire Session component. This means all the session methods will return null. Remove the 'Session' key from $this->generate() and you should be good.