CakePHP 3.10 adding a Form field with '_id' in name, automatically makes it a select field - cakephp

CakePHP 3.10 adding a Form field with '_id' in name, automatically makes it a select field. I want to know if this is something that is done in our App specifically by previous developer and if so, how/where would I look?
Alternatively, if it's a CakePHP thing, where can I get documentation on it?
Controller:
public function add()
{
$building = $this->Buildings->newEntity();
if ($this->request->is('post')) {
//code for after form submission
}
$this->set(compact('building'));
}
View:
<div>
<?= $this->Form->create($building) ?>
<fieldset>
<legend><?= __('Add Building') ?></legend>
<?php
echo $this->Form->control('test_id'); <!-- this field type will be a select field -->
echo $this->Form->control('name');
?>
</fieldset>
<?= $this->Form->button(__('Submit')) ?>
<?= $this->Form->end() ?>
</div>

If you read this V3 documentation you can see:
https://book.cakephp.org/3/en/views/helpers/form.html#namespace-Cake\View\Helper
So, the cause of this is because cakephp understand you have a belongsTo or hasOne association between Buildings model and Test model.
If you have a test_id column in buildings table, you are saying to cakephp that tests table has one or has many building/s.
you can force the type of Form Helper using the condition:
$this->Form->control('test_id', ['type' => 'text']);
Extra note: when you have this case you could use virtual fields to show what is the test_id that the Building belongs.
For example: you could show the concatenation of the test name and author name (assuming these two fields exist in the test table) like:
Into TestEntity.php
namespace App\Model\Entity;
use Cake\ORM\Entity;
class Test extends Entity
{
protected function _getTestIndicator()
{
return $this->name . ' ' . $this->author_name;
}
}
Into the view:
echo $user->test_indicator;

Related

Populating a dropdown list in Cakephp from database values

I'm trying to populate the values in a dropdown list in Cakephp v2.6.1.
The values are being retrieved, but the form helper is not creating dropdown listboxes as expected: All I am getting displayed on the form is the Submit button - The id fields are send as hidden fields to the web page. Can someone point out where I am going wrong?
Coursemembership controller
<?php
App::uses('AppController', 'Controller');
class CoursemembershipsController extends AppController {
public $components = array('Paginator', 'Session');
...
public function add() {
if ($this->request->is('post')) {
$this->Coursemembership->create();
if ($this->Coursemembership->save($this->request->data)) {
$this->Session->setFlash(__('The coursemembership has been saved.'));
if ($this->Coursemembership->saveAssociated($this->request->data)) {
return $this->redirect(array('action' => 'index'));
} else {
$this->Session->setFlash(__('The coursemembership could not be saved. Please, try again.'));
}
}
}
$students = $this->Coursemembership->Student->find('list');
$courses = $this->Coursemembership->Course->find('list');
$this->set(compact('students', 'courses'));
}
Add view
<div class="coursememberships form">
<?php echo $this->Form->create('Coursemembership'); ?>
<?php echo $this->Form->input('Student.id'); ?>
<?php echo $this->Form->input('Course.id'); ?>
<?php echo $this->Form->end(__('Submit')); ?>
</div>
Variables (from the debug add-in)
View Variables
students(array)
1Cromwell
2Lionheart
3Knight
7four
8five
9six
10seven
11eight
courses(array)
1Applied Speliology
2Aggravated aggrandisement
3Crossword Puzzles 101
5Aggravated aggrandisement
6Applied Speliology
You're not setting the field names for your inputs properly. The id field is the primary key by convention and will be added as a hidden field (usually used for editing, so your Model knows what id to alter).
You should add the fields as they are set in the Coursemembership datasource (probably a database table called coursememberships, if you're following convention for database design). This should show the fields you need and save the proper data:
echo $this->Form->create('Coursemembership');
echo $this->Form->input('Coursemembership.student_id');
echo $this->Form->input('Coursemembership.course_id');
echo $this->Form->end(__('Submit'));
Everything you want to save should go to the Coursemembership model. You should only need to save anything to the Student or Course model if you'd actually wanted to add a new student or course to your application. For assigning a membership of a Student to a Course, the above code should do the trick.

Using Wordpress, how can I display posts that are in multiple categories?

I am trying to retrieve posts in Wordpress that belong in two categories. Each post must belong in both categories.
Here is my query:
<?php $myPosts = new WP_Query('category_name=featured+news&posts_per_page=10'); ?>
<?php if($myPosts->have_posts()) : ?>
<?php while($myPosts->have_posts()) : $myPosts->the_post(); ?>
<article>
<h2><?php the_title(); ?></h2>
<?php the_content(); ?>
</article>
<?php endwhile; ?>
<?php endif; ?>
In this example, 'featured' and 'news' are the slugs of two categories. I am using the plus symbol (+) with the 'category_name' parameter in my query to indicate that posts must be in both categories, as suggested here.
For some reason, this isn't working and I'm not sure why. I am getting this error:
PHP Warning: urldecode() expects parameter 1 to be string
It's referencing the query.php file:
wp-includes/query.php
Why can the query not interpret featured+news as a string? I figure I must be missing something. Any help is very much appreciated.
I'm not sure why the plus symbol (+) isn't working but using category__and instead works.
$featuredID = get_category_by_slug('featured')->term_id;
$newsID = get_category_by_slug('news')->term_id;
$myPosts = new WP_Query(array('category__and' => array($featuredID, $newsID), 'posts_per_page' => 10));

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.

How to use tinymce plugin?

I have tried many times to use this plugin and I failed.
I am following documentation, but it does not work for me.
I am posting the simple code here, to know what wrong I am doing.
1-I put this plugin in this folder app/plugins
2- I add TinyMce helper to articles_controller
<?php
class ArticlesController extends AppController {
// good practice to include the name variable
var $name = 'articles';
// load any helpers used in the views
var $helpers = array('Html', 'Form','TinyMce.TinyMce');
/**
* index()
* main index page of the formats page
* url: /formats/index
*/
function index(){
// get all formats from database where status = 1
$articles = $this->Article->find("all") ;
$this->set('articles', $articles);
}
function admin_add() {
// if the form data is not empty
if (!empty($this->data)) {
// initialise the format model
$this->Article->save($this->data);
// set a flash message
$this->Session->setFlash('The Format has been saved');
// redirect
$this->redirect(array('action'=>'index'));
} else {
// set a flash message
$this->Session->setFlash('The Format could not be saved. Please, try again.','default', array('class' => 'flash_bad'));
}
}
}
?>
3- in the view file articles/admin_add.ctp I added the editor
// i think the problem in this code
<?php $this->TinyMce->editor(array(
'theme' => 'advanced'
)); ?>
<div class="formats form">
<?php echo $form->create('Article');?>
<fieldset>
<legend>Add a article</legend>
<?php
// create the form inputs
echo $this->Form->input('title');
echo $this->Form->input('content'); ?>
</fieldset>
<?php echo $form->end('Add');?>
</div>
<ul class="actions">
<li><?php echo $html->link('List Articles', array('action'=>'index'));?></li>
</ul>
You need to put tinymce files into your js assets
Then you have to add into section of your layout.
Then you'll need to init tinymce according to example provided on tinymce website (ex: full tinymce layout) and configure it according to your requirements.
I'd personally would not rely on such cake plugins, when actions required to get things working are not many and they are simple enough.

cakephp: how to display associated records of associated records

My objective is to display records for a related child model (once removed) in the view. I understand that setting the recursive value to '1' returns the current model, its owner(s), plus their associated models.
What I don't know how to do is display this in the view.
My approach has been to create a varialable in the controller holding the value of the associated model ID, but that hasn't work.
*I should also mention that I'm using a sluggable behavior for tournaments, so it's not $id that is used but $slug.
Here are the model view controller details:
Model
tournament - has many tournamentDetails
tournamentDetails - has many updates
updates - belongs to tournamentDetails
tournaments controller
action = view
class TournamentsController extends AppController
function view($slug = null) {
if (!$slug) {
$this->Session->setFlash(__('Invalid Tournament.', true));
$this->redirect(array('action'=>'index'));
}
$this->Tournament->recursive = 1;
$tournament = $this->Tournament->findBySlug($slug);
$updates = $this->Tournament->TournamentDetail->Update->find('all', array('conditions'=>array('update.tournament_detail_id' => $this->data['tournament_details'] ['id'] )) );
$this->set(compact('tournament','updates' ));
Tournament view. This is display the 'tournament details' and (ideally) related tournament detail 'updates'
<h2><?php echo $tournament['Tournament']['name']; ?></h2>
<?php foreach ($tournament['TournamentDetail'] as $tournamentDetail): ?>
<h1><?php echo $tournamentDetail ['title']; ?></h1>
<p><?php echo $tournamentDetail ['body']; ?></p>
<?php endforeach; ?>
<?php foreach ($updates['Update'] as $update): ?>
<h4>Update: <?php echo $update ['date']; ?></h4>
<p> <?php echo $update ['Update'] ['title']; ?></p>
<p><?php echo $update ['Update'] ['body']; ?></p>
<?php endforeach; ?>
when I debug $updates, this is all I see:
Array
(
)
I don't know what I'm doing wrong here.
Is it not correct to construct the find conditions by using:
('conditions'=>array('update.tournament_detail_id' => $this->data['tournament_details'] ['id'] )
Thanks for the help.
Paul
You can use the Containable Behavior to specify in detail what fields you want to obtain from associated models, associated models to associated models and so on. Then you will find all data inside the array $tournament, like in the examples in the link.
EDIT (in response the OP comment). I think that the problem may be using the magic findBy method. You would need to substitute that with the standard find, like in this example
$tournament = $this->Tournament->find('first', array(
'conditions' => array(
'slug' => $slug
),
'contain' => array(//Put here the settings for Containable
)
));

Resources