Symfony2 form - edit saved data - symfony-2.1

I'm looking for guidance how to have form prefilled with data taken from existing object. I guess it should be working with method setData, I was expecting something simple like
$form->setData($existingObject) but no success.
For better explanation let's have a simple example.
I have form where user inputs his personal data. Form is created in controller by calling form.factory,
$form = $this->get('form.factory')->create(new personType());
I have form class "personType" and this form class has defined data_class object called "person". User submits form, data are saved in object person and this object is saved in session. I need to have option reopen the form and fill in data saved in object stored in session.

In your controller, you need to create/find your object then pass it to your createForm
$task = new Task();
$task->setTask('Write a blog post');
$task->setDueDate(new \DateTime('tomorrow'));
$form = $this->createForm(new TaskType(), $task);
http://symfony.com/doc/master/book/forms.html#creating-form-classes
In your exemple, try
$person = ...;
$form = $this->get('form.factory')->create(new personType(), $person);

Related

laravel pagination Method links does not exist

I am building a dynamic query using eloquent based on user inputs.
$query = \App\Model::query();
if($this == request('that')){
$query->where(...); // building dynamic query based on user inputs
}
and finally user can type number of records shown per page in an html input field named count or checking a checkbox input type named all and following code completes dynamic query in back-end:
if (request('all')) {
$result = $query->get();
}else {
$result = $query->paginate(request('count'));
}
Also in front-end I have following code to show pagination links:
{{$result->links()}}
The problem is when user chooses to show all records we face following error:
Method links does not exist.
links method is not callable when we retrieve objects via get() method. What is the best practice in order not to face this error?
It's because ->get() method return collection instead of paginator model Illuminate\Pagination\LengthAwarePaginator. So I can recomment you send some addition variable from your controller which indicate if you need execute $result->links().
Controller:
return view('yourView', [showPagination => is_null(request('all'))]);
View:
#if($showPagination)
{{$result->links()}}
#endif

Load data in custom form by using Kentico 9

I searched the whole web and I couldn't found any good topic which expose the proper way to do it.
I have a very simple web which I developed using Kentico 9 CMS. This web only contains two subpages and a header to navigate between those.
The "Home" subpage contains a custom form which remains connected to a SQL table which is populated every time you press submit with certain data.
On the other hand, the other page, shows the stored data by using a custom web part which connects to the DB by using BizFormItemProvider and this object is used as a layer to binding the data in a control.
Now is my point. If you see, there is a button to "Edit" a certain row and my intention is to Redirect to "Home" (which contains the form) and sending via QueryString the ID of the row attempted to edit.
I was unable to understand how can you re-fill the form with its data using an ID.
Maybe because I never worked with a CMS before, I'm looking the development such as pure ASP.NET and it could not be the correct one.
Custom
Given that your solution uses a custom form for entering the data, as well as a custom web part for listing the stored data, you will need to use a custom solution to handle the editing of data, as well.
In the custom webpart on the Home page, in a load event, you can retrieve the form data and set the values on the form controls.
protected void Page_Load(object sender, EventArgs e)
{
// Ensure that the form is not being posted back,
// to prevent entered data from being overwritten
if(!IsPostBack)
{
// Get the form item ID from the query string
var personId = QueryHelper.GetInteger("personId", 0);
if(personId > 0)
{
// Get the biz form item, and set form control values
var bizFormItem = BizFormItemProvider.GetItem(personId, "customFormClassName");
txtFirstName.Text = bizFormItem.GetStringValue("FirstName", string.Empty);
}
}
}
Similarly, when Submit is clicked, you can update the existing form item with the new data
protected void btnSubmit_OnClick(object sender, EventArgs e)
{
// Get the form item ID from the query string
var personId = QueryHelper.GetInteger("personId", 0);
if(personId > 0)
{
// Retrieve the existing biz form item,
// and update it from the form control values
var bizFormItem = BizFormItemProvider.GetItem(personId, "customFormClassName");
bizFormItem.SetValue("FirstName", txtFirstName.Text);
bizFormItem.Update();
}
else
{
// Your code for inserting a new form item...
}
}
The Kentico way
You should really consider using the Kentico form engine for accomplishing this task. Instead of using a custom form for entering the data, use the built-in On-line form webpart.
The benefits are numerous, such as:
Ability to set the form layout through the CMS, and use alternative layouts
Automatic confirmation email to the submitter of the form, as well as notification emails to the administrators
To accomplish your task, you can customise the On-line form webpart to support loading of existing data.
In the bizform.ascx.cs file, add code to the SetupControl method:
protected void SetupControl()
{
if (StopProcessing)
{
// Existing code...
}
else
{
// Existing code...
// Get the form item ID from the query string
var personId = QueryHelper.GetInteger("personId", 0);
if(personId > 0)
{
// Get the biz form item, and set form control values
var bizFormItem = BizFormItemProvider.GetItem(personId, "customFormClassName");
if(bizFormItem != null)
{
// Set the item ID
viewBiz.ItemID = bizFormItem.ItemID;
}
}
}
}
This will automagically switch the form to Edit mode, instead of Insert mode, as soon as you set the ItemID property. Clicking the Submit button will save changes on the existing form item.
You will not need to worry about validation in your code, and inserting data will still work.
Is this a contact form that you are using Kenticos built in form application for, or is it a custom form? If it is a custom form you can create a transformation with a link that will contain the ID. If it is a biz form, you can still create a transformation in Page Types (create a new page type and select "The page type is only a container without custom fields"), then write a custom query to get the biz form data, and use a repeater to display the data with that transformation.

Docuemt postopen event not operating on profile document

I need to save serial number of the document in a profile document and here is a code of action Execute Script:
if (document1.isNewNote()){
var pdoc:NotesDocument=database.getProfileDocument("LastNumber","")
var lnm=pdoc.getItemValue("lastNumber")[0];
var inputText6:com.ibm.xsp.component.xp.XspInputText = getComponent("inputText6");
inputText6.setValue(lnm);
pdoc.replaceItemValue("lastNumber",lnm);
pdoc.save();
}
This code is not opening profile document at all. Any thing wrong in the code?
"LastNumber" is the name of the form used to create Profile Document ?
this profile document already exist ?
there are no reader fields in this profile document ?
you have an error on this line : var pdoc:NotesDocument=database.getProfileDocument("LastNumber","") ?
or you have debug it and see that pdoc is null ?
instead of pdoc.getItemValue("lastNumber")[0] you can use pdoc.getItemValueInteger("lastNumber") to get a typed result
I supposed that this field contains a number and you want to increment it
instead of using inputText field you can set value directly with document1.setValue("NumberField", lnm);
I second the caution Per is suggesting. Profile documents can be a beast. You should abstract access to the "next number" into a SSJS function call. Btw. in your code snippet you don't actually increment the last number. Also: if your input text control is bound, go after the data source, not the UI.
A crude way (I would use a managed application bean for better isolation) for a better function could be this:
if(document1.isNewNote() {
document1.setValue("DocumentNumber",applicationTools.getNextNumber());
}
Then in a SSJS library you would have:
var applicationTools = {
"getNextNumber" : function() {
synchronized(applicationScope){
var pdoc:NotesDocument=database.getProfileDocument("LastNumber","");
if (!applicationScope.lastNumber) {
applicationScope.lastNumber = pdoc.getItemValueInteger("lastNumber");
}
applicationScope.lastNumber++;
pdoc.replaceItemValue("lastNumber",applicationScope.lastNumber);
pdoc.save(); //Make sure pdoc is writeable by ALL!!!!
pdoc.recycle();
return applicationScope.lastNumber;
}
},
"someOtherUtility" : function(nameToLookup, departments) {
// more stuff here
}
}
Which, in some way has been asked before, but not for a profile field. Someone still could simply go after the applicationScope.lastNumber variable, which is one of the reasons why I rather use a bean. The other: you could do the saving asynchronously, so it would be faster.
Note: in any case the number generation only works when you have a non-replicating database. But abstracting the function opens the possibility to replace fetching the number from the profile with a call to a central number generator ... or any other mechanism ... without changing your form again.

How to secure the segment passed to the controller in CI

I am trying to pass a segment to a controller. The url is like base_url/controller/function/seg1. I want to ensure that if the user try to enter the segment in the address bar, the controller would make sure there are not other words to be proceeded except the segment I want to pass.
For example, If the user tries to type base_url/main/function/(change this to other words) in address bar, the controller will filter the segment. I am not sure how to do it and would appreciate if someone can help me out.
Okay, so the best way to "secure" against such things would be to simply create a session at the time the user logs into your site with two values stored in that session;
1) Their database primary key id, and
2) a session item called 'logged_in'
At the time that your user would log into your site, you would store those two values like this;
$this->session->set_userdata('logged_in', true);
$this->session->set_userdata('user_id', $id);
Where $id is pulled from their user record during authentication.
Now that you have those in there, the next part would be that, in your controller, you would put an if statement in that checks if the user is logged in, as such;
function show($id) {
if($this->session->userdata('logged_in')) {
$posts = $this->Model_posts->get_user_posts($id);
}
}
Now, in your model, you would create a function for pulling the record that you want the user to be able to view based on their user_id. We'll say user posts for example.
function get_user_posts($user_id, $post_id) {
$sql = "SELECT * FROM posts WHERE user_id = ? AND id = ?";
$binds = array($user_id, $post_id);
$qry = $this->db->query($sql, $binds);
$result = array();
while($row = $qry->result_array()) {
array_push($result, $row);
}
return $result;
}
Now, when a logged in user or visitor tries to access records that don't belong to them, they will not retrieve any records because the select statement limits what's returned only to that user.
The structure you have there is
base_url/controller/action
So, your controller is already "filtering" it out because if you don't have a method/function in the controller (methods = actions) then your controller will trigger a 404 Page Not Found error. Of coarse, you could then handle your errors however you see fit, but from what you presented, the item you wish to filter is known as a controller action.
So for instance;
http://www.base_url.com/users/add
denotes that you wish to call the add (function) in the users controller.
If you want to pass the add action an argument, then you would do this as;
http://www.base_url.com/users/show/1
Where show would be a controller action and 1 would be the id of the user you wish to show.
I know it seems like I'm giving a basic intro to MVC methodologies, but like I said, the structure you showed plays out like I described.
Hope this helps.

Transfer data from one JSF page to ProcessAction() method of FacesPortlet

Here is what I am trying to do.
I want the data from jsf page1 to be available in jsf page2 which is a popup window opened by page1.
Both have separate managed beans.
I tried using sessions but it resulted in null pointers.
I somehow managed to get the data in page2 using window.opener() in javascript.
Now I want this data to be available in the processAction() method of FacesPortlet.
Tried using request.getParameter, request.getAttributes, all in vain.
After a lot of research I somehow managed to send some hard coded data in processAction() method. But I am unable to send the value from page1.
Here is how I am sending the hardcoded value.
<form name="uploadbaseline" method="post"
enctype="multipart/form-data" action="<portlet:actionURL><portlet:param name = "page" value = "someval"/></portlet:actionURL>">
This is followed by the other fields inside the form.
I get the value in processAction() method like this
System.out.println("valuefrompage1"+request.getParameter("page"));
This returns "someval".
Now I try to assign the value from page1 using javascript using the following code.
var val = window.opener.document.getElementById("BaseLine:EngineModel").value;
var actionval = "<portlet:actionURL><portlet:param name='page' value=" + val.value + "/></portlet:actionURL>";
document.uploadbaseline.action = actionval.value;
document.uploadbaseline.submit();
This returns the value "+ val.value +" as it is and not the actual value in the "val" variable.
Please guide me in the right direction.
Keenly looking forward to your replies.
Thanks.
Found the solution finally.
The problem lies in the enctype attribute of my form.
This prevents me from accessing the page fields using the regular request.getParameter.
This needs to be handled in a different way.
Here is how.
for (Iterator requestItems = upload.parseRequest(request).iterator(); requestItems.hasNext();) {
item = (FileItem) requestItems.next(); // Get each item in the request
if (!item.isFormField()) {
//handle the file data
} else {
System.out.println((String)item.getString());
}
}

Resources