Frontend

Now we have all the required code on the API to accept URLs. Let's see the changes required on the frontend to be able to post the URL and show the result on the wall. As usual, let's have a look at a screenshot of the folder structure and new files.

Frontend

Creating the link entity

Let's create a new entity to store the data related to a link. This class is really easy and just contains getters and setters for the column names. Let's see a couple of examples and the list of properties contained inside the class.

protected $id = null;
protected $userId = null;
protected $url = null;
protected $title = null;
   protected $createdAt = null;
protected $updatedAt = null;

Now let's see two simple getters and setters.

public function setTitle($title)
{
    $this->title = $title;
}
    
public function setUpdatedAt($updatedAt)
{
    $this->updatedAt = new DateTime($updatedAt);
}
    
public function getId()
{
    return $this->id;
}
    
public function getUserId()
{
    return $this->userId;
}

Adding the LinkForm.php file

Of course if we want the users to use the new functionality, we should provide them with a way to provide us with the information we need. This form will allow them to specify the URL of the web page they want to share, as simple as that. Again, this form will have one special section, the field used for the URL information.

namespace WallForms;

use ZendFormElement;
use ZendFormForm;

As usual we start with the following declaration of namespaces at the beginning of the class:

class LinkForm extends Form

The declaration of the class will follow the same approach as the other forms we already created, but in this case we are not implementing the InputFilterProviderInterface interface because the field we are going to use will automatically add the needed validators.

public function __construct($name = null)
{
    parent::__construct('link-content'),
    $this->setAttribute('method', 'post'),
    $this->setAttribute('class', 'well input-append'),
        
    $this->prepareElements();
}

The structure of the form will follow the approach of having specialized methods for each task. That leaves us with the following constructor:

public function prepareElements()
{
    $this->add(array(
        'name' => 'url',
        'type'  => 'ZendFormElementUrl,
        'attributes' => array(
            'class' => 'span11',
        ),
    ));
    $this->add(new ElementCsrf('csrf'));
    $this->add(array(
        'name' => 'submit',
        'attributes' => array(
            'type'  => 'submit',
            'value' => 'Submit',
            'class' => 'btn'
        ),
    ));
}

This is how the prepareElements() method looks. As you can see we are adding the field URL to allow the users to insert the URL and is a Url element. This includes the new URL HTML5 element on the form and automatically adds the ZendValidateUri validator. Remember that if we use the ZendFormElementUrl element we should use the formUrl() helper on the view.

Creating the image-content-form.phtml file

This file will take care of rendering the fields associated with the LinkForm. The content is similar to other files we saw before.

<?php $form = $this->form; ?>
<?php $form->prepare(); ?>
<?php echo $this->form()->openTag($form) ?>
<!-- Url input text -->
<?php echo $this->formElement($form->get('url')); ?>
<?php echo $this->formElementErrors($form->get('url')); ?>

<!-- Submit button -->
<?php echo $this->formElement($form->get('submit')); ?>

<!-- CSRF -->
<?php echo $this->formElement($form->get('csrf')); ?>
<?php echo $this->formElementErrors($form->get('csrf')); ?>

<?php echo $this->form()->closeTag() ?>

Did you see it? Yes, we are not using the formUrl() helper, instead, we are using the usual formElement() helper. Why? Because the formElement() helper will introspect the field we are trying to print and will decide which is the best helper for the job and will use it. It's like a universal view helper for form elements.

Extending the index.phtml file

As usual we cannot put the entire code of the view because it's huge but we are going to see in this section how to include the new form on the view.

<div id="wall-link">
    <?php echo $this->partial(
        'forms/link-content-form.phtml', 
        array('form' => $linkContentForm)
    ); ?>
</div>

As you can see, we are calling a partial that includes the elements of the form and we are passing the form itself as a parameter to that partial. When you render a partial you can pass all the variables you want and change its name using the second parameter of the partial() method. It accepts an array and the names you use on the keys will become the name of the variable that contains the value you pass inside the partial.

<?php elseif ($entry instanceOf WallEntityLink) : ?>
    <p>
        <a href="<?php echo $entry->getUrl() ?>">
            <?php echo $entry->getTitle() != ''? 
                $entry->getTitle() : $entry->getUrl(); ?>
        </a>
    </p>
<?php endif; ?>

This is the code we will use to represent a link on the wall. It's a simple link pointing to the URL and using the title of the website as a text of the link. It's really simple but you can extend the base system to fetch the images of the web page and use one of them to represent the page similar to Facebook. You can also extract the content of the description meta tag and use it here to further explain the purpose of the website.

Changing the User.php file

As we did with the other content, we should adapt the User entity to create new entities for the links. This is really easy and we just need to add the following lines to the setFeed() method:

public function setFeed($feed)
{
    $hydrator = new ClassMethods();
    
    foreach ($feed as $entry) {
        if (array_key_exists('status', $entry)) {
            $this->feed[] = $hydrator->hydrate(
                $entry, new Status()
            );
        } else if (array_key_exists('filename', $entry)) {
            $this->feed[] = $hydrator->hydrate(
                $entry, new Image()
            );
        } else if (array_key_exists('url', $entry)) {
            $this->feed[] = $hydrator->hydrate(
                $entry, new Link()
            );
        }
    }
}

As you can see we are adding a new case to our if block and testing if the entry has a key called url, in which case we proceed to hydrate a new Link object.

Modifying the IndexController.php file

The following is the last file we have to modify in this chapter to make the new functionality work:

use WallFormsLinkForm;

This is the first thing to do. We should add this line to be able to use the new form we created for the users.

Then we should make three changes in the indexAction() method in order to include and process the new form.

$linkForm = new LinkForm();

This line goes in the block where we create the other forms; we just need to create an instance of the new one.

if (array_key_exists('url', $data)) {
    $result = $this->createLink($linkForm, $user, $data);
}

This second block goes inside the if block that checks if we are dealing with a POST request. In here, we are checking the type of the request based on the keys found in the data and based on that call, the specialized method createLink(), which will take care of the rest. The rest of the code should look familiar because it is the same one we used on the two previous forms but we have just adapted the names of the variables to match the new forms.

$linkForm->setAttribute(
    'action', 
    $this->url()->fromRoute(
        'wall', 
        array('username' => $user->getUsername())
    )
);

This is the last block of code we need in this method and we will add it at the end, next to the other two similar blocks of code we have. We are just setting the URL for the action parameter on the form.

Now let's review the new method createLink() that we have to add. It's really simple and looks like the other one we already added, specially with the createStatus() method that is basically the same.

protected function createLink($form, $user, array $data)
{
    return $this->processSimpleForm($form, $user, $data);
}

The following screenshot shows how our wall looks with the new functionality:

Modifying the IndexController.php file
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset