Home  >  Article  >  Backend Development  >  Symfony form and page implementation skills, symfony form skills_PHP tutorial

Symfony form and page implementation skills, symfony form skills_PHP tutorial

WBOY
WBOYOriginal
2016-07-13 10:09:02745browse

Symfony form and page implementation skills, symfony form skills

The examples in this article describe the symfony form and page implementation techniques. Share it with everyone for your reference. The details are as follows:

Symfony development is very simple, but the number of functions is still lacking. Now it's time to do some interaction between the askeet site and the user. The foundation of HTML interaction--besides linking--is the form.

Our goal here is to allow users to log in and browse through the list of questions on the home page. This is fast for development and allows us to recall the previous content.

Login form

There is a user in the test data, but the program has no way to verify it. Next we are going to add a login form to every page of the program. Open the global layout file askeet/apps/frontend/templates/layout.php and add the following line of code before the connection to about:

Copy code The code is as follows:
  • The current layout places these links after the web debugging toolbar. To see these links, click on the 'Sf' icon to collapse the debug toolbar.

    Now you need to create the user module. The question module was generated on the second day. This time we just asked symfony to create the module framework, and we will write the code ourselves.

    Copy the code The code is as follows:
    $ symfony init-module frontend user

    This framework contains a default index action and an indexSuccess.php template. Delete them as we don't need them.

    Create user/login action

    Copy the code The code is as follows:
    In the user/actions/action.class.php file, add the following login action:

    public function executeLogin()
    {
    $this->getRequest()->setAttribute('referer', $this->getRequest()->getReferer());

    Return sfView::SUCCESS;
    }

    This action saves the referer in the request attribute. This attribute can then be stored in a hidden area for use by the module, so that the form's intended action can be redirected to the original referer after a successful login.

    The statement return sfView::SUCCESS passes the action execution result to the loginSuccess.php module. This statement is implemented in an action that does not contain a return statement, which is why the default module for an action is called actionnameSuccess.php.

    Before we start working more on actions, let’s take a look at modules.

    Create loginSuccess.php module

    Many human-computer interactions on the web use forms, and Symfony organizes the creation and management of forms by providing a collection of form helpers.

    In the askeet/apps/frontend/modules/user/templates/ directory, create the following loginSuccess.php module:

    Copy code The code is as follows:






    get('nickname')) ?>









    getAttribute('referer')) ?>


    This module is our first use of form helpers. These Symfony functions can help us automatically write form tags. form_tag() opens a tag, uses POST as the default action, and points to the action passed as argument. The input_tag() helper generates an tag and automatically adds an id attribute based on the first argument passed; the default value is obtained from the second argument. We can find more information about form helpers and the HTML code they generate in the relevant chapters of the Symfony book.

    The essence here is that this action will be called when the form is submitted. So let's go back and look at this action.

    Handle form submission

    Replace the login action we just wrote with the following code:

    Copy code The code is as follows:
    public function executeLogin()
    {
    if ($this->getRequest()->getMethod() != sfRequest::POST)
    {
    // display the form
    $this->getRequest()->setAttribute('referer', $this->getRequest()->getReferer());
    }
    else
    {
    // handle the form submission
    $nickname = $this->getRequestParameter('nickname');

    $c = new Criteria();
    $c->add(UserPeer::NICKNAME, $nickname);
    $user = UserPeer::doSelectOne($c);

    // nickname exists?
    If ($user)
    {
    // password is OK?
    If (true)
              {
    $this->getUser()->setAuthenticated(true);
               $this->getUser()->addCredential('subscriber');

               $this->getUser()->setAttribute('subscriber_id', $user->getId(), 'subscriber');
               $this->getUser()->setAttribute('nickname', $user->getNickname(), 'subscriber');

    // redirect to last page
                return $this->redirect($this->getRequestParameter('referer', '@homepage'));
    }
    }
    }
    }

    The login action can be used to display the login form and process it at the same time. Accordingly, he must know the environment in which he is called. If the action is not called in POST mode (because it is requested by a link): This is exactly the situation we discussed above. If requested in POST mode, this action will be called by the form and processed accordingly.

    This action will get the value of the nickname field from the request parameter, and query the User table to see if this user exists in the database.

    In the future a password control will be used to assign credentials to users. But now, all this action does is store the user's id and nickname attributes in a session attribute. Finally, the action redirects to the original referer field hidden in the form, which is passed as a request parameter. If this field is empty, the default value will be used.

    Here we need to pay attention to the difference between the two types of attribute sets in this example: request attributes ($this->getRequest()->setAttribute()) are saved for the template, and only the answer is sent to the referer will be forgotten. session attributes ($this->getUser()->setAttribute()) are saved throughout the user session lifetime, and they can be accessed by other actions in the future. If we want to know more about properties, we can check out the Parameter Saver section of the Symfony book.

    Assign permissions

    It is a good thing that users can log in to the askeet website, but users do not log in just for fun. You need to log in to post a new question, express interest in a certain question, and evaluate a comment. Other actions will be open to non-logged-in users.

    To set a user as authenticated, we need to call the ->setAuthenticated() method of the sfUser object. This object also provides a certificate mechanism (->addCredential()) to restrict access through configuration. This is explained in detail in the User Certificates section of the Symfony book.

    This is the purpose of the following two lines:

    Copy code The code is as follows:
    $this->getContext()->getUser()->setAuthenticated(true);
    $this->getContext()->getUser()->addCredential('subscriber');

    When the nickname is recognized, not only the user data is stored in the session attribute, but the user is also assigned access rights to restricted parts of the website. Tomorrow we will see how to restrict program access to authenticated users.

    Add user/logout action

    There is one last tip about the ->setAttribute() method: the last parameter (subscriber in the above example) defines the namespace where the attribute is stored. A namespace not only allows a name that exists in another namespace to be assigned to an attribute, but also allows all such attributes to be quickly removed using a single command:

    Copy code The code is as follows:
    public function executeLogout()
    {
    $this->getUser()->setAuthenticated(false);
    $this->getUser()->clearCredentials();

    $this->getUser()->getAttributeHolder()->removeNamespace('subscriber');

    $this->redirect('@homepage');
    }

    Using namespaces saves us the trouble of removing these properties one by one: it’s just a single line.

    Update layout

    Currently this layout still displays a 'login' link even if the user is logged in. Let's fix this. In the askeet/apps/frontend/templates/layout.php file, modify the code we modified at the beginning of today’s guide:

    Copy code The code is as follows:
    isAuthenticated()): ?>

  • getAttribute('nickname', '', 'subscriber').' profile', 'user/profile') ?>



  • Now it's time to test, we can display any page of the program, click on the 'login' link, enter an available nickname ('anonymous' for example) and verify. If 'login' at the top of the window changes to 'sign out', then everything we have done is correct. Finally, try logging out to see if the 'login' link appears again.

    Problem Organization

    As thousands of Symfony enthusiasts visit the askeet website, more and more questions will be displayed on the home page. In order to avoid slowing down the request speed, random browsing of the question list becomes a problem that must be solved.

    Symfony provides an object for this purpose: sfPropelPager. It will encapsulate the request for data, so that only the records displayed on the current page will be queried. For example, if a page is initialized with only 10 questions per page, the request to the data will only be limited to 10 results, and the offset will be set to match within the page.

    Modify question/list action

    In the previous exercise, we saw the display action of the question module:

    Copy code The code is as follows:
    public function executeList ()
    {
    $this->questions = QuestionPeer::doSelect(new Criteria());
    }

    We will modify this action to pass an sfPropelPager to the template instead of passing an array. At the same time, we will sort the questions according to the quantity of interest:

    Copy code The code is as follows:
    public function executeList ()
    {
    $pager = new sfPropelPager('Question', 2);
    $c = new Criteria();
    $c->addDescendingOrderByColumn(QuestionPeer::INTERESTED_USERS);
    $pager->setCriteria($c);
    $pager->setPage($this->getRequestParameter('page', 1));
    $pager->setPeerMethod('doSelectJoinUser');
    $pager->init();

    $this->question_pager = $pager;
    }

    The initialization of the sfPropelPager object specifies which object class it contains, and the maximum number of objects that can be placed on a page (2 in this example). ->The setPage() method uses a request parameter to set the current page. For example, if the value of this page parameter is 2, sfPropelPager will return results from 3 to 5. If the value of the page request parameter changes to 1, the page will return results from 1 to 2 by default. We can learn more about the sfPropelPager object and its methods in the pages chapter of the Symfony book.

    Use a default parameter

    It is a good idea to put constants in the configuration files we use. For example, the results per page (2 in this example) can be replaced by a parameter in our custom program configuration. Change the sfPropelPager line above with the following code:

    Copy code The code is as follows:
    ..
    $pager = new sfPropelPager('Question', sfConfig::get('app_pager_homepage_max'));

    The pager keyword here is used as a namespace, which is why it appears in the parameter name. We can see more about custom configuration and naming custom parameter rules in the Configuration section of the Symfony book.

    Modify listSuccess.php template

    In the listSuccess.php template, add the following line of code:

    Copy code The code is as follows:
    Replace

    with

    Copy code The code is as follows:
    getResults() as $question): ?>

    Thus the page displays the list of results stored in the page.

    Add page view

    There is one more thing you need to do in this template: page views. Now, all the template does is display the first two questions, but we should add the functionality to the next page, and the ability to go back to the previous page. To finish adding these features, we need to add the following code after the template:

    Copy code The code is as follows:

    haveToPaginate()): ?>

    getPreviousPage()) ?>

    getLinks() as $page): ?>
    getPage(), $page, 'question/list?page='.$page) ?>
    getCurrentMaxLink()) ? '-' : '' ?>


    ', 'question/list?page='.$question_pager->getNextPage()) ?>
    getLastPage()) ?>

    This code uses various methods of the sfPropelPager object, as well as ->haveToPaginate(), this function will only return true when the number of requested results exceeds the page size; and ->getPreviousPage(),- >getNextPage(), ->getLastPage() all have explicit meaning; ->getLinks() function provides an array of page numbers; and ->getCurrentMaxLink() function returns the last page number.

    This example also shows a Symfony link helper: link_to_unless() will output a regular link_to() if the test as the first argument is false, otherwise it will output a non-link text, and use simple The package.

    Did we test this page? We should test. This modification isn't complete until we verify it with our own eyes. To test, open the test data file created on day three and add some questions for the page view to be displayed. Rerun the import data batch file and request the home page again.

    Add routing rules for subpages

    By default, the page rules are as follows:

    http://askeet/frontend_dev.php/question/list/page/XX

    Now we use routing rules to make these pages easier to understand:

    http://askeet/frontend_dev.php/index/XX

    Open the apps/frontend/config/routing.yml file and add the following content at the top:

    Copy code The code is as follows:
    popular_questions:
    url: /index/:page
    param: { module: question, action: list }

    And add additional routing rules for the login page:

    Copy code The code is as follows:
    login:
    url: /login
    Param: { module: user, action: login }

    Refactor

    Model

    The

    question/list action executes code related to the model, which is why we want to move this code into a module. Use the following code to replace the question/list action:

    Copy code The code is as follows:
    public function executeList ()
    {
    $this->question_pager = QuestionPeer::getHomepagePager($this->getRequestParameter('page', 1));
    }

    And add the following method in the QuestionPeer.php class in lib/model:

    Copy code The code is as follows:
    public static function getHomepagePager($page)
    {
    $pager = new sfPropelPager('Question', sfConfig::get('app_pager_homepage_max'));
    $c = new Criteria();
    $c->addDescendingOrderByColumn(self::INTERESTED_USERS);
    $pager->setCriteria($c);
    $pager->setPage($page);
    $pager->setPeerMethod('doSelectJoinUser');
    $pager->init();

    Return $pager;
    }

    The same idea applies to the question/show action we wrote yesterday: the usage of the Propel object to retrieve the question by its stripped title should belong to this module. So use the following code to change the question/show action code:

    Copy code The code is as follows:
    public function executeShow()
    {
    $this->question = QuestionPeer::getQuestionFromTitle($this->getRequestParameter('stripped_title'));

    $this->forward404Unless($this->question);
    }

    Add the following code in the QuestionPeer.php file:

    Copy code The code is as follows:
    public static function getQuestionFromTitle($title)
    {
    $c = new Criteria();
    $c->add(QuestionPeer::STRIPPED_TITLE, $title);

    Return self::doSelectOne($c);
    }

    Template

    The question list shown in question/templates/listSuccess.php will be used in some places in the future. So we put the template code that displays the problem list in a _list.php fragment and replace the contents of listSuccess.php with the following simple code:

    Copy code The code is as follows:

    popular question

    $question_pager)) ?>

    I hope this article will be helpful to everyone’s symfony framework programming.

    www.bkjia.comtruehttp: //www.bkjia.com/PHPjc/947922.htmlTechArticleSymfony form and page implementation skills, symfony form skills This article describes the symfony form and page implementation skills with examples. Share it with everyone for your reference. The details are as follows: Symfony development is very simple...
    Statement:
    The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn