Cakephp 4 can't change locales - cakephp

I'm trying to set two buttons so depending of the language user can switch to the other.
In my default.php I have this, to change on click on the link AppController:
<li class="nav-item">
<?php
if (I18n::getLocale() !== 'en_US'){ ?>
<?= $this->Html->link('EN', ['action' => 'changeLang']); ?>
<?php
}else{ ?>
<?= $this->Html->link('ES', ['action' => 'changeLang']); ?>
<?php } ?>
</li>
My AppController
public function changeLang():void
{
if (I18n::getLocale() !== 'en_US'){
I18n::setLocale('en_US');
}else{
I18n::setLocale('es_ES');
}
$this->redirect($this->referer());
}
My default.po (in locales/es/default.po)
#: ./src/Controller/AddressController.php:72
#: ./src/Controller/UserController.php:81
msgid "Usuario registrado."
msgstr "Registered user."
It goes in the correct lines but the code doesn't change. What I'm doing wrong?
I used var_char to see if it pass the ifs correctly and it does.
A also change the app.php in config to from
'defaultLocale' => env('APP_DEFAULT_LOCALE', 'en_US'),
to
'defaultLocale' => env('APP_DEFAULT_LOCALE', 'es_ES'),
and it also works.
If I use I18n::setLocale('es_ES'); on AppController inicialize it works, so why does it not work in my function?

I18n::setLocale is a per-request setting. You're not doing anything in the code shown to save it to a session or cookie, so it will only ever be set to the default value when starting up, or to your specified value just before redirecting (which starts a new request, which resets to the default value).

Related

Sending form errors back to view via redirect

I recently started picking up on CakePHP and now I'm trying to build a contact form for my site.
It seems to work in validating the forms, but there's something I want to do now.
I want it to show any errors that occur (like missing a required field).
However, I want it to show 2 different possible states:
- A user error (user forgot a field or the field doesn't meet the requirements), show this below the field (using Bootstrap 4)
- A server error (mail couldn't send from the server - for example, the SMTP server is down), shown using the Flash
I've been searching far and wide for this, but I couldn't get any further on this without posting a question myself.
Below is all the code that I'm using (running CakePHP 3.6)
src/Template/Pages/contact.ctp (controlled by the PagesController):
<div class="container">
<div class="row no-banner">
<div class="col-md-6">
<h4>Contact Form</h4>
<div style="padding-bottom:25px;">
Got a question? we'd love to hear it from you!<br />
Send us a message and we'll respond as soon as possible!
</div>
<?= $this->Flash->render(); ?>
<?= $this->Form->create("Contact",array("url"=>"/contact","class"=>"contact-form","id"=>"contact-form")); ?>
<?= $this->Form->control("name",array("placeholder"=>"Your Name","label"=>false,"class"=>"form-control")); ?>
<?= $this->Form->control("email",array("placeholder"=>"Your Email","label"=>false,"class"=>"form-control")); ?>
<?= $this->Form->control("subject",array("placeholder"=>"The Subject","label"=>false,"class"=>"form-control")); ?>
<?= $this->Form->textarea("message",array("placeholder"=>"Your Message","label"=>false,"class"=>"form-control")); ?>
<?= $this->Form->button('Submit',array("class"=>"btn")); ?>
<?= $this->Form->end(); ?>
</div>
<div class="col-md-6">
<h4>Social Media</h4>
<div style="padding-bottom:25px;">
We are active on a variety of of social media, feel free to like and follow us!
</div>
<i class="fab fa-facebook social-media-icon"></i>
<i class="fab fa-discord social-media-icon"></i>
<?= $this->Form->errors; ?>
</div>
</div>
</div>
src/Controller/ContactController.php:
<?php
namespace App\Controller;
use App\Controller\AppController;
use App\Form\ContactForm;
class ContactController extends AppController {
public function add() {
$contact = new ContactForm();
if ($this->request->is('post')) {
if ($contact->execute($this->request->getData())) {
$this->Flash->success('We will get back to you asap!');
$this->redirect($this->referer());
} else {
$this->Flash->error('There was an issue sending your mail. Please try again later!');
$this->redirect($this->referer());
}
}
$this->set('contact', $contact);
}
}
src/Form/ContactForm.php:
<?php
namespace App\Controller;
use App\Controller\AppController;
use App\Form\ContactForm;
class ContactController extends AppController {
public function add() {
$contact = new ContactForm();
if ($this->request->is('post')) {
if ($contact->execute($this->request->getData())) {
$this->Flash->success('We will get back to you asap!');
$this->redirect(array('controller' => 'Pages','action' => 'display','contact'));
} else {
$this->Flash->error('There was an issue sending your mail. Please try again later!');
$this->redirect($this->referer());
}
}
$this->set('contact', $contact);
}
}
Don't redirect, because you don't need to. Instead of using the Pages controller to display the form put the form in your controllers view: /Contacts/add.ctp. No need to call redirect() then.
The errors are already added to the form and the form helper will find them because you're passing the form object to Form->create().
If you want to make it more complicated than needed stick to your implementation and simply write the errors to the session and in the action that receives it read them from the session and set them to the form object via setErrors().

Show calendar to specific users based on custom field

I use the calendar plugin from http://tri.be/ on a worpress website for a private website (it’s like an intranet..).
On this calendar I put all the planned meetings, but I would like that the current logged in user can see only the events he/she is supposed to join.
I thought that I can create a custom field, named, for example, “mustjoin” and put there a list of registered usernames as values.
Then do a check on the page.
If the current logged in username is in that list, he/she can see the event on the calendar.. otherwise not.
Something like :
if ( $current_user->user_login == get_field(mustjoin)) { ?>
//CODE IF OK
<?php } else { ?>
//CODE ELSE<?php } ?>
This of course is working when I have only one username in the ACF box, as soon as I put more than one username.. it doesn't work anymore because it is not an Array..
How can I create an array with ACF? what function and how can I interrogate that array?
This is the part of the code I need to show IF the current user username is in the value list ‘mustjoin’
<?php while ($day['events']->have_posts()) : $day['events']->the_post() ?>
<?php tribe_get_template_part('month/single', 'event') ?>
<?php endwhile; ?>
On another forum a guy told me to use this snippet :
function searchForName($name, $array) {
foreach ($array as $key => $val) {
if ($val['nickname'] === $name) {
return true;
}
}
return null;
}
$current_user = wp_get_current_user();
if(searchForName($current_user->user_login,get_field('mustjoin'))):
//CODE GOES HERE
endif;
But it doesn't work..
Thank you for your comment. This is the code, and it works at 99%.
<?php $current_user = wp_get_current_user(); ?>
<?php global $user_login;
get_currentuserinfo(); ?>
<?php $lookforuser = get_field('mustjoin') ?>
<?php if (strpos($lookforuser, $user_login) !== false) { ?>
<?php while ($day['events']->have_posts()) : $day['events']->the_post() ?>
<?php tribe_get_template_part('month/single', 'event') ?>
<?php endwhile; ?>
<?php } ?>
But I need to ask you if this code is "clean" or if I can make it better/faster.
Because when I open the calendar page, I can't see anything.. as soon as I refresh the page, all the events (where I am supposed to join) appear.
How can I fix it? (I tried with different computers/browsers, no changes..)
Thank you.
Thanks to another guy on another website, finally it works at 100%!
I just needed to check the user before the events loop :
<?php $current_user = wp_get_current_user(); ?>
<?php global $user_login;
get_currentuserinfo(); ?>
<?php while ($day['events']->have_posts()) : $day['events']->the_post(); ?>
<?php $lookforuser = get_field('mustjoin'); ?>
<?php if (strpos($lookforuser, $user_login) !== false)
tribe_get_template_part('month/single', 'event'); ?>
<?php endwhile; ?>
Thank you anyway for the right suggestion and help.

pagination not working when clicked next button

Controler
public function search() {
$this->Paginator->settings = $this->paginate;
$this->loadmodel('Usermgmt.User');
if ($this->request -> isPost()) {
$this->User->set($this->data);
$keyword=$this->data['Doctors']['search'];
//$this->loadmodel('Usermgmt.User');
$cond=array('OR'=>array("User.username LIKE '%$keyword%'","User.email LIKE '%$keyword%'", "User.first_name LIKE '%$keyword%'", "User.last_name LIKE '%$keyword%'"));
//$result = $this->paginate('User',array('conditions'=>$cond));
$result = $this->paginate('User',array($cond));
$this->set('result', $result);
}
}
View
<?php
if (!empty($result)) { $sl=0;
foreach ($result as $row1) {
//print_r($row1);
$sl++; ?><div style="width:100%;display:inline-block;">
<div style="float:left">
<?php
//echo $row1['id'];
echo $this->Html->link($this->Html->image('../files/user/photo/'.$row1 ['User']['photo_dir'].'/'.$row1 ['User']['photo'], array('width' => '180', 'height' => '180')),
array('controller'=>'Profiles','action'=>'index',$row1['User']['id']),
array('escape' => false));
?>
</div>
<div>
<?php echo h($row1['User']['first_name'])." ".h($row1['User']['last_name'])."</br>";
echo h($row1['User']['username'])."</br>";
echo h($row1['User']['email'])."</br>";
echo h($row1['User']['mobile'])."</br>";
echo h($row1['UserGroup']['name'])."</br>";
?></div>
<div style="clear:both;"></div>
</div>
<?php }?>
<?php echo $this->Paginator->prev('previous'); ?>
<?php echo $this->Paginator->numbers(); ?>
<?php echo $this->Paginator->next('Next'); ?>
<?php }?>
here am search the user name or user details like fname, email like and display in view page
here i get output with pagination like 1 2 3 4 only first page displays when i click next page that shows empty pages may be $result getting unset how to solve this ??
The variable result is only sometimes set
if ($this->request->isPost()) {
...
$result = $this->paginate('User',array($cond));
$this->set('result', $result);
}
The variable result is only set for POST requests - clicking a link is not a post request, therefore the result variable is undefined.
Ensure you are paginating a GET request
There are several solutions, but the simplest solution to "How to paginate post data" is to not do so. Change your search form to use GET, and ensure the get parameters persist when paginating a request.
At the very least the controller code needs to call paginate and set for the variables in the view to exist irrespective of how the controller action was reached.

Calling a element after login

I have a post index view calling a element which content input field for comment.
I call it in this way
<?php echo $this->element('addcomment', array('post_id' => $post['Post']['id'])); ?>
This work fine, I pass the post id parameter, in the addcomment element, because the post_id input field is hidden in the addcomment. and of course I dont want that the user type the post id.
I have set up the authorization mechanism in order to allow adding comment to the user identified (connected).
When a non-connected user try to add a comment, he receives the login screen.
After login, he is redirected to the add commment form. The problem is that in the mean time it loose the value of the post_id variable.
Rem: If the user is connected before adding comments to the post, it works.
Dont hesitate to contact me in case my explanation is not clear or if you need more information.
This is my addcomment element
<div class="Addcomment form">
<?php
echo $this->Form->create('Comment', array(
'url' => array('controller' => 'comments', 'action' => 'add')
)); ?>
<fieldset>
<legend><?php echo __('Add Comment'); ?></legend>
<?php if (isset($current_user['id']) && isset($post_id)): ?>
<?php $this->request->data['Comment']['user_id'] = $current_user['id']; ?>
<?php $this->request->data['Comment']['post_id'] = $post_id; ?>
<?php echo $this->Form->input('post_id', array('type' => 'hidden')); ?>
<?php echo $this->Form->input('user_id', array('type' => 'hidden')); ?>
<?php else: echo $this->Form->input('post_id'); ?>
<?php endif; ?>
<?php echo $this->Form->input('content', array('class' => 'comment')); ?>
</fieldset>
<?php echo $this->Form->end(__('Submit')); ?>
</div>
As per i understand your problem. You can use a session variable to store a post id which should not affected if user logs in. And using this session you can redirect a user to particular post after login.
Set a session value before redirecting user to login.
$this->Session->write('last_post_id',YOUR_POST_ID);
Redirect user to the post if user successfully logged in and if you find a session value not empty.
if ($this->Session->check('last_post_id') && $this->Session->read('last_post_id') != '') {
$this->redirect(YOUR_URL_TO_POST . '?postid=' . $this->Session->read('last_post_id'));
exit;
}else{
//NORMAL REDIRECTION
}
Hope this will help you. Unset session last_post_id after redirection and if no longer required.

Yii file upload is not validating file type

I am validating the file type to be uploaded. The validation rule does not seem to work. I only want to accept jpg files but when I try putting pdf files, it still accepts it and does not give any error. Please help. I don't know what I'm doing wrong.
View:
<?php $form=$this->beginWidget('CActiveForm', array(
'id'=>'document-form',
'enableAjaxValidation'=>true,
'enableClientValidation'=>true,
'clientOptions'=>array('validateOnSubmit'=>true), //This is very important
'htmlOptions'=>array('enctype'=>'multipart/form-data'),)); ?>
<p class="note">Fields with <span class="required">*</span> are required.</p>
<?php echo $form->errorSummary($model); ?>
<div class="row">
<?php echo $form->labelEx($model,'barangay_clearance'); ?>
<?php echo $form->fileField($model,'barangay_clearance'); ?>
<?php echo $form->error($model,'barangay_clearance'); ?>
</div>
<div class="row buttons">
<?php echo CHtml::submitButton($model->isNewRecord ? 'Create' : 'Save'); ?>
</div>
<?php $this->endWidget(); ?>
Model:
public function rules()
{
// NOTE: you should only define rules for those attributes that
// will receive user inputs.
return array(
array('barangay_clearance', 'file', 'allowEmpty'=>true, 'types'=>'jpg', 'message'=>'Jpg files only', 'on'=>'insert'),
array('barangay_clearance, barangay_status, zoning_clearance, zoning_status, sanitary_clearance, sanitary_status, occupancy_permit, occupancy_status, fire_safety, fire_safety_status', 'safe'),
// The following rule is used by search().
// Please remove those attributes that should not be searched.
array('document_id, business_id, barangay_clearance, barangay_status, zoning_clearance, zoning_status, sanitary_clearance, sanitary_status, occupancy_permit, occupancy_status, fire_safety, fire_safety_status', 'safe', 'on'=>'search'),
);
}
Controller: (Note: I haven't really changed the controller yet except for activating the ajaxvalidation function and creating an instance of another model)
public function actionCreate($id)
{
$model=new Document;
$busModel = Business::model()->findByPk($id);
// Uncomment the following line if AJAX validation is needed
$this->performAjaxValidation($model);
if(isset($_POST['Document']))
{
$model->attributes=$_POST['Document'];
if($model->save())
$this->redirect(array('view','id'=>$model->document_id));
}
$this->render('create',array(
'model'=>$model,
'busModel'=>$busModel,
));
}
This should work perfectly.
array('barangay_clearance', 'file','types'=>'jpg', 'allowEmpty'=>true, 'on'=>'update', 'on'=>'insert'),
You didn't assign any scenario to model. If model you use in form widget is instance of Document then this:
$model=new Document;
has to be replaced with this:
$model=new Document('insert');
since rule declaration
array('barangay_clearance', 'file', 'allowEmpty'=>true, 'types'=>'jpg', 'message'=>'Jpg files only', 'on'=>'insert'),
says that it will be applied only on "insert" scenario.
I hope it helps.

Resources