ways of making OpenPNE3 plugin

select languages

index

at first

OpenPNE3 allowed us to add various functions as a plugin. OpenPNE3 uses symfony framework, but OpenPNE3 plugin has different structure from symfony plugin. This document tells you how to make OpenPNE3 plugin.

precondition

This document is valid when the following conditions are completed.

  • The condition that it is possible to install and work OpenPNE3 is prepared.
  • It is possible to work by console in above-mentioned condition.

make framework of plugin

OpenPNE3 has tasks to make framework of plugin. Use these tasks and make framework to make plugin.

move to directory of OpenPNE3

Move to the directory which is installed OpenPNE3 by console.

From now, I explain on the assumption that it is installed OpenPNE3 in "/var/www/OpenPNE3" .

$ cd /var/www/OpenPNE3

practice task

Next, practice task to make plugin. I'll show you the case of making plugin named "opSamplePlugin" as an example.

By practicing the following task, "opSamplePlugin" is added in "plugins" directory of OpenPNE3.

$ symfony opGenerate:plugin opSamplePlugin

It is made 4 directories under "opSamplePlugin" directory, which is added newly.

apps
conf
i18n
lib
supplementation : about rule of naming plugin

It has not yet been decided a rule of naming plugin. But,

"opHogehogePlugin"

I'm thinking as above-mentioned..

add module

The most different from symfony plugin is it can arrange "apps" directory. It is possible to arrange module of each application under it. And the tasks to make these automatically is prepared.

I'll show you the the case of adding "hello" modul to pc_frontend application that is used by SNS members from PC as an example. By practicing the following task, blank "modules" directory is contained under "apps" directory, and "pc_frontend" directory is made.

$ symfony opGenerate:app opSamplePlugin pc_frontend

Moreover, add "hello" modul to "pc_frontend" . By practicing the following task, "hello" directory is made in "pc_frontend/modules" directory.

$ symfony opGenerate:module opSamplePlugin pc_frontend hello

http://sns.example/

When it is the URL of OpenPNE3, access the following URL and if it is indicated the page "Module "hello" created" , framework is completed.

http://sns.example/hello

change indication

edit action

Under "plugins/opSamplePlugin/app/pc_frontend/modules/hello" , "actions" and "templates" directories are made. From the beginning, "actions.class.php" is prepared in "actions" directory. Contents are the follows:

…(omitted)…
class helloActions extends sfActions

{ /** * Executes index action * * @param sfRequest $request A request object */ public function executeIndex($request) { $this->forward(’default’, ‘module’); } }

$this->forward('default','module');

It is reason that it is forward to page "Module “hello” created" . Change this part to follows:

return sfView::SUCCESS;

 …(omitted)…
class helloActions extends sfActions
  {
  /**
  * Executes index action
  *
  * @param sfRequest $request A request object
  */
  public function executeIndex($request)
  {
   return sfView::SUCCESS;
  }
}

edit template

Next, edit template. From the beginning, "indexSuccess.php" is prepared in "templates" directory. "If sfView::SUCCESS is returned by executeIndex(), it indicates this template. The content is blank file, so try to edit something. I'll show you the case of entering "Hello world!" as an example."

http://sns.example/hello

When you access the URL, it is indicated the logo of OpenPNE and the text: "Hello world!" .

change presence of authentication

In this state, this "hello" modul can be indicated nothing login. To use login authentication, make new "confing" directory and "security.yml" file in "hello" directory. And edit it like follows:

all:
  is_secure: on
  credentials: SNSMember

Because it is YAML, use two spaces key not a tab for indent. Then please delete cash by symfony cc.

If it is completed, you can't access the following URL without login.

http://sns.example/hello

If you log in and access it, the page which has menu is indicated.

make database model

It is way of making original database model for plugin. "I'll show you the case of making MyNews From now, I explain in MyNews example."

Way of making database model for plugin is as the symfony manual.

<URL:http://www.symfony-project.org/book/1_2/17-Extending-Symfony#Plug-In%20File%20Structure>(English)

Make "schema.yml" in "config" directory just under plugin directory. The need field to make MyNews is the follows:

ID: It is possible to use the model 1-1, but in this time, I assigned peculiar key to this table. member ID: It is outside key of member model at core. text:

update time:

To make this model, edit "schema.yml" like follows:

propel: _attributes: { package: plugins.opSamplePlugin.lib.model }

member_news: id: ~ member_id : { type: integer, foreignTable: member, foreignReference: id } content: { type: longvarchar } updated_at: ~

Like "security.yml" ,please be careful about YAML. Use two spaces key not a tab for indent.

If you don't designate any options, about id and designated field become primary key automatically, and autoincrement is effective.

"By using ***_id, it become outside key of ***table. If the table is on same "schema.yml" file, it become outside key of the table automatically. But, declaration of member table is in another place.Please designate foreignTable certainly"

! When you use core model at the α-version stage, please be careful because model may change.

updated_at become the field at which update time register automatically when it updates. After save this file,

$ symfony openpne:install

Make database model again with command.

! It will be impossible to add model made newly without initialization all database model of OpenPNE3 in the future.

add parts

When you add new function to a certain page(ex.page_h_home) in customize of OpenPNE2, you needed to edit action of this page and edit template, and so on…。 But in OpenPNE3, it is possible to add new parts to specific page by only adding plugin.

We call this structure "template extension".

OpenPNE3 has the structure that template composed of some parts of template. Parts has ID and it is possible to insert another parts in front of and behind it.

It is necessary to insert new items into home and profile to implement "My News! Function" .

Insert form of "My News!" newly under information. At first, try to display some words under information.

add partial

At first, add template which is inserted newly.

opSamplePlugin/apps/pc_frontend/modules/hello/templates

Add _sampleParts.php to mentioned above. This is the partial which is displayed under information.

Look at the follows about partial of symfony.

<URL:http://www.symfony-project.org/book/1_2/07-Inside-the-View-Layer#Templating>(English)

Enter "Hello world!!" to _samplePlarts.php.

make establishment of layout

To insert template which is made for this time into member/home which is home of OpenPNE3, make member directory newly at follows:

opSamplePlugin/apps/pc_frontend/modules

And make config directory in member directory. Make view.yml file in config directory and edit the file like follows:

homeSuccess:
  customize:
    sampleParts:
      template: [hello, sampleParts]
      parts: [information]
      target: [after] 
homeSuccess

It is member module. Add establishment of homeSuccess template here.(HomeSuccess template is the template which is called when home action is successed.)

customize

It allows us to extend template.

sampleParts

It is template name.

template

It designates certain partial.

parts

It designates id of parts.

target

It decide id which is designated by parts to arrange.

In this way, it is inserted hello/sampleParts after information of homeSuccess.

After adding and editing the establishment file, please delete cash certainly by follows command.

$ symfony cc

If you access fome, it is displayed "Hello world!!" under information.

make form

edit form

From the beginning there is MemberNewsForm.class.php at opSamplePlugin/lib/form. This is the class which is made automatically when model is made. If you use it without processing, it provides you with form which allows you to edit all field. (id , member_id, content, updated_at form which allow you to edit field)

The item which I can edit in MyNews! function is only content field. And edit it as follows to deal with it.

MemberNewsForm.class.php
<?php

(omitted comment line )
class MemberNewsForm extends BaseMemberNewsForm
{
  public function configure()
  {
    $this->setWidgets(array(
      ’content’ => new sfWidgetFormTextarea()
    ));

    $this->setValidators(array(
      ’member_id’ => new sfValidatorPropelChoice(array(’model’ => ‘Member’, ‘column’ => ‘id’)),
      ’content’ => new sfValidatorString(array(’required’ => false))
    ));

    $this->widgetSchema->setNameFormat(’member_news[%s]‘);
  }
}

Look at follows about ways of making form.

The symfony Forms Book - Chapter 1 - make form
<URL:http://www.symfony-project.org/book/forms/1_2/ja/01-Form-Creation>
The symfony Forms Book - Chapter 4 - integrate into Propel(At the point of symfony1.1)
<URL:http://symfony.xrea.jp/1.1/forms_book/04-Propel-Integration.html>

operate model

Insert this form into partial. Change opSamplePlugin/apps/pc_frontend/modules/hello/templates/_sampleParts.php to follows:

_sampleParts.php

<?php $criteria = new Criteria(); $criteria->add(MemberNewsPeer::MEMBER_ID,$sf_user->getMember()->getId()); $memberNews = MemberNewsPeer::doSelectOne($criteria);

$form = new MemberNewsForm($memberNews);

include_box(’MyNews’,'MyNews’,”,array(’form’=>$form,’url’=>’hello/updateNews’));

Look at follows about operating model

The Definitive Guide to symfony - Chapter8 - inside of model layer(At the point of symfony1.1)

<URL:http://symfony.xrea.jp/1.1/book/08-Inside-the-Model-Layer.html>

At this code, the instance of form which was edited some time ago is made. Contents which is registered at DB is established as default value by giving instance of model to constructor. When I outputs form, I use include_box() which is included PartsHelper. PartsHelper is used to insert parts for OpenPNE3 and it is loaded from the beginning.

Explain of include_box($id, $title = ”, $body = ”, $option = array())
$id

It is ID of this parts. Please be careful not to use same ID in same page.

$title

It is text which is displayed at title of this parts.

$body

It is content of this parts. In MyNews! Function case, it is blank because it displays form.

$option
It is option of this parts.
form
It is parameter which is needed when it uses form. When it gives form, it gives instance of form to this parameter.
url
It designates the action place when form is submitted.

If you update after edit it, edit form of MyNews! Is displayed home of OpenPNE.

edit action

Mention about action which is occurred when MyNews is contributed to plugins/opSamplePlugin/apps/pc_frontend/modules/hello/actions/actions.class.php.

In "operate model" , Name of action at post-point is updateNews. Add "executeUpdateNews" which is new method to hello action which is declared in this file. Name of method is execute name of action(). (The beginning of the name is capital letter.)

actions.class.php
<?php
// (omitted comment line)..

class helloActions extends sfActions
{
  // (omitted comment line)..
  public function executeIndex($request)
  {
    return sfView::SUCCESS;
  }

  public function executeUpdateNews($request)
  {
    // Check if it is POST request.
    if ($request->isMethod(sfRequest::POST))
    {
      // Take out one line which corresponds with member ID of mine from member_news.
      $criteria = new Criteria();
      $criteria->add(MemberNewsPeer::MEMBER_ID,$this->getUser()->getMember()->getId());
      $memberNews = MemberNewsPeer::doSelectOne($criteria);

      // Set the one line which is took out as an initial value of memberNewsForm which is made at the last time
      $memberNewsForm = new MemberNewsForm($memberNews);

      // Get a parameter which is POSTed.
      $param = $request->getParameter(’member_news’);
      $param['member_id'] = $this->getUser()->getMember()->getId();

      // Bind the parameter.
      $memberNewsForm->bind($param);

      // Check the entered value if it is right.
      if ($memberNewsForm->isValid())
      {
        // Save to database.
        $memberNewsForm->save();
      }
    }
    // At last redirect to my home.
    return $this->redirect(’@homepage’);
  }
}

It is enable to get my own member information by follows action: $this->getUser()->getMemer() This is the instance of class Member which is set my information. And it is enable to get $sf_user で $this->getUser() by template. So it is enable to get my member information by $sf_user->getMember()

make confirming function on profile page

plugins/opSamplePlugin/apps/pc_frontend/modules/hello/templates

Add _sampleParts2.php of partial to mention above. And edit like follows, to display MyNews.

_sampleParts2.php
<?php
// id parameter(It is member id which is disgnated when profile page is displayed.)
// Get it. If there is no id like my own profile, substitute my member id for $member_id.
$memberId = $sf_request->getParameter(’id’, $sf_user->getMember()->getId());

//Take out one line which corresponds with  $memberId which is got from member_news table.
$criteria = new Criteria();
$criteria->add(MemberNewsPeer::MEMBER_ID, $memberId);
$memberNews = MemberNewsPeer::doSelectOne($criteria);

$body = “”;
// If there is line, substitute content of content field for $body.
if ($memberNews)
{
  $body = $memberNews->getContent();
}

// Include Parts helper.(OpenPNE3 own helper)
// Output $body by using include_box of a function.
// A means of include_box was explained in last article.
include_box(’MyNews’,'MyNews’,nl2br($body));

change establishment of layout

Designate sampleParts2 for template.

plugins/opSamplePlugin/apps/pc_frontend/modules/member/config/view.ymlを以下のようにします。

view.yml
homeSuccess:
… (omitted) …
      target: [after]

profileSuccess:
  customize:
    sampleParts2:
      template: [hello, sampleParts2]
      parts: [profile]
      target: [before]

After editing establishment file, delete cash by symfony cc. In this way, content of MyNews is displayed on prfile page.

MyNews! function is completion.

Translate by TasukuTaira