Symfony2: Admin Generátor helyett AdminBundle beta, teszt

A Symfony2 nem tartalmazza beépítve az admin generátort, egy külön projekt jött létre az admin felületek készítésére szolgáló részhez, melynek jelenleg AdminBundle a neve.
Az admin generátor a Symfony 1.x verzióinak egyik nagy fegyvere volt, egyszerűen fogalmazva: szerintem sok cégnek emiatt érte meg leginkább Symfonyt használni, mert jelentősen fel tudta gyorsítani a fejlesztési folyamatokat és nem mellékesen az egyedi admin felületek fejlesztéséhez is jól tudta használni a gyakorlott “kéz”, mert ki lehetett másolni a generált kódokból mindenféle finomságot 🙂 amire szükségünk lehetett, aki használta tudja miről beszélek és szerintem egyet is tud érteni velem abban, hogy a Symfony a népszerűségét az Admin generátorának nagy mértékben köszönhette.

Ahogyan az elő bekezdés elején írtam, a Symfony2-ben annyit változott a helyzet, hogy az eddigi admin generátor szerepét egy új bundle vezi át, melynek a neve egyelőre AdminBundle. Itt halkan megjegyezném azt is, hogy egyelőre a Diem sem működik Symfony2 alatt, így a Symfony2 még eléggé szegényes CRUD tekintetében, de ez biztosan változni fog, mert CRUD és Admin felületek, pontosabban írva: hatékony, rugalmas és egyszerűen használható CRUD és Admin felületek nélkül nehéz lesz a népszerűséget megtartania a Symfonynak, lásd pl. a yii framework CRUD generátorát: kicsi, gyors, rugalmas, de nem célom az összehasonlítgatás.

Nézzük, hogy mit is tud jelen állapotában az AdminBundle, ne feledd, hogy erősen fejlesztés alatt álló projektről lez szó, mely teli lehet hibákkal, ráadásul nincs hozzá jó leírás, és maga az alaprendszer, amihez illezkedik (Symfony2) még béta állapotban sincs… szóval nem egyszerű a képet összerakni. 🙂

Az AdminBundle itt található (még a neve is változhat…):

https://github.com/sonata-project/AdminBundle

A Symfony2 – erről már fanyalogtam egy régebbi blogbejegyzésben, nem kezdem újra :), nincs híján az új elnevezéseknek, valószínűleg egy ilyen újdonság lesz a Sonata is, ami egy bundle gyűjtemény, és szerintem eddig csupa hasznosnak tűnő projektek kaptak benne helyet, ezek listáját megnézheted itt:

https://github.com/sonata-project

Az AdminBundle is a Sonata része, ahhoz, hogy használni tudjuk telepíteni kell néhány másik bundlet, ezek a következők:

jQueryBundle
BluePrintBundle
MenuBundle

Telepítés:

Telepítheted a doksiban leírt módon, de Windows alól ez nehézkes volt, mert nálam nem volt meg a Git támogatás 🙂 ezért a fapados megoldást választottam, egyszerűen letöltöttem a szükséges Bundlekat tömörítve, majd az src könyvtár alá bemásoltam őket…

Tehét csináltam két könyvtárat:

mkdir src/Sonata
mkdir src/Knplabs

Ezek a Bundle-k kellenek:

src/Sonata/AdminBundle
src/Sonata/jQueryBundle
src/Sonata/BluePrintBundle
src/Knplabs/Bundle/MenuBundle

Egyzerű, le kell tölteni mindegyiket, bemásolni a megfelelő helyekre, ha ez megvan, akkor be kell állítani rájuk az autoloadot és az AppKernel.php-ban a kötelező sorokat:

Autoload:

      'Sonata'                    =>__DIR__.'/../src',  
'Knplabs' =>__DIR__.'/../src',

AppKernel:

                new Sonata\AdminBundle\SonataAdminBundle(),  
new Knplabs\Bundle\MenuBundle\KnplabsMenuBundle(),

Ennyi.

Az egész folyamat nagyobbik része ez után veszi kezdetét… a saját Bundle létrehozása, ezen belül az Entity-ben az ORM létrehozása, majd az Admin könyvtár létrehozása…nagyon babrás, őszintén bevallom, hogy nagyon elment az egésztől a kedvem, de azért végigcsináltam, már ameddig tudtam.

A tesztben létrehoztam egy Alma nevű csodálatos 😀 Bundlét, “adtam hozzá” egy egyszerű ORM-et, mely egy Alma nevű táblát definiált, 3 darab mezővel, nagyrészt e köré szőttem az egész tesztemet, húsvéti unaloműzőnek megfelelt, de amúgy…no comment.

Az Alma bundle létrehozása:

parancs:
php app/console init:bundle “Teszt/AlmaBundle” src

autoload:

 $loader->registerNamespaces(array(  
'Symfony' => array(__DIR__.'/../vendor/symfony/src', __DIR__.'/../vendor/bundles'),
'Sensio' => __DIR__.'/../vendor/bundles',
'JMS' => __DIR__.'/../vendor/bundles',
'Doctrine\\Common' => __DIR__.'/../vendor/doctrine-common/lib',
'Doctrine\\DBAL' => __DIR__.'/../vendor/doctrine-dbal/lib',
'Doctrine' => __DIR__.'/../vendor/doctrine/lib',
'Monolog' => __DIR__.'/../vendor/monolog/src',
'Assetic' => __DIR__.'/../vendor/assetic/src',
'Acme' => __DIR__.'/../src',
'Teszt' =>__DIR__.'/../src',
));

Appkernel.php:

     $bundles = array(  
new Symfony\Bundle\FrameworkBundle\FrameworkBundle(),
new Symfony\Bundle\SecurityBundle\SecurityBundle(),
new Symfony\Bundle\TwigBundle\TwigBundle(),
new Symfony\Bundle\MonologBundle\MonologBundle(),
new Symfony\Bundle\SwiftmailerBundle\SwiftmailerBundle(),
new Symfony\Bundle\DoctrineBundle\DoctrineBundle(),
new Symfony\Bundle\AsseticBundle\AsseticBundle(),
new Sensio\Bundle\FrameworkExtraBundle\SensioFrameworkExtraBundle(),
new JMS\SecurityExtraBundle\JMSSecurityExtraBundle(),
new Acme\DemoBundle\AcmeDemoBundle(),
new Teszt\AlmaBundle\TesztAlmaBundle,
);

app/config/config.yml:

   orm:  
auto_generate_proxy_classes: %kernel.debug%
default_entity_manager: default
entity_managers:
default:
mappings:
AcmeDemoBundle: ~
TesztAlmaBundle: ~

Eléggé sok lépés mire egy Bundle-t rendesen regisztrálunk…

Most egy Entitiy-t kéne létrehoznom…ehhez kell csinálnom a TesztAlmaBundle-n (src/Teszt/AlmaBundle) belül egy Entity nevű mappát, amelybe egy Alma.php-t kell tennem és mivel PHP kóddal szeretném leírni a modellemet, ezért ennek a tartalma ez lett:

 <?php  
namespace Teszt\AlmaBundle\Entity;
/**
* @orm:Entity
*/
class Alma
{
/**
* @orm:Id
* @orm:Column(type="integer")
* @orm:GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* @orm:Column(type="string", length="255")
*/
protected $name;
/**
* @orm:Column(type="string", length="255")
*/
protected $price;
/**
* @orm:Column(type="integer")
*/
}

Nagyon primitív, de tesztnek megteszi…

A Routingok használatához muszáj kicsit elkanyarodni a témától, az új Symfonyban le tudjuk kérdezni az összes érvényes routingot:

 $ php app/console router:debug  

ez hasznos parancs, nekem ami nagyon tetszik, hogy annotációkkal is lehet routingokat definiálni.

Például így:

 <?php  
namespace Teszt\AlmaBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
class DefaultController extends Controller
{
/**
* @extra:Route("/almaIndex", name="DemoalmaIndex")
* @extra:Template()
*/
public function indexAction()
{
return $this->render('TesztAlmaBundle:Default:index.html.twig');
}
}

és erre még hivatkozni kell az app/config/routing.yml-ben is, így:

 _almaIndex1:  
resource: "@TesztAlmaBundle/Controller/DefaultController.php"
type: annotation

Node visszatérve az ORM-hez, nekem tetszik is, meg nem is az új Symfony elgondolása, mint azt már írtam korábban, szerintem túl van spekulálva, de legalább már körvonalazódnak azok a megoldások és eszközök, melyek 1-2 hónapja még egyáltalán nem látszódtak egy külső szemlélőnek, ez talán nem is baj, ami nagyobb gond az az, hogy szerintem a Symfony2-ből még nagyon sokáig nem lesz egy jól dokumentált, kipróbált rendszer, szerintem ez év vége előtt biztosan nem.

Node, visszatérve az Admin generátorhoz… 🙂

 php app/console doctrine:generate:entities TesztAlmaBundle  

Ha a fenti parancs sikeresen lefut, akkor valami hasonló osztály fog keletkezni:

 <?php  
// Acme/HelloBundle/Entity/User.php
namespace Teszt\AlmaBundle\Entity;
/**
* @orm:Entity
*/
class Alma
{
/**
* @orm:Id
* @orm:Column(type="integer")
* @orm:GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* @orm:Column(type="string", length="255")
*/
protected $name;
/**
* @orm:Column(type="string", length="255")
*/
protected $price;
/**
* @orm:Column(type="integer")
*/
/**
* Get id
*
* @return integer $id
*/
public function getId()
{
return $this->id;
}
/**
* Set name
*
* @param string $name
*/
public function setName($name)
{
$this->name = $name;
}
/**
* Get name
*
* @return string $name
*/
public function getName()
{
return $this->name;
}
/**
* Set price
*
* @param string $price
*/
public function setPrice($price)
{
$this->price = $price;
}
/**
* Get price
*
* @return string $price
*/
public function getPrice()
{
return $this->price;
}
}

Ami felülírta az eredeti Alma.php-mat az Entity könyvtáron belül… a régit pedig átnevezte ~Alma.php-nak…

Ezen a ponto hoztam létre az admin osztályomat, ezt az TesztAlma bundle alatt egy Admin nevű könyvtárba raktam:

 <?php  
namespace Teszt\AlmaBundle\Admin;
use Sonata\AdminBundle\Admin\Admin;
use Sonata\AdminBundle\Form\FormMapper;
use Sonata\AdminBundle\Datagrid\DatagridMapper;
use Sonata\AdminBundle\Datagrid\ListMapper;
class AlmaAdmin extends Admin
{
}
<

A neve AlmaAdmin.php.

Ezek után az admin generátor Routingjait regisztrálnom kellett a app/config/routing.yml-ban:

 # app/config/routing.yml  
admin:
resource: '@SonataAdminBundle/Resources/config/routing/sonata_admin.xml'
prefix: /admin
_sonata_admin:
resource: .
type: sonata_admin
prefix: /admin

és ha most az előbb leírt parancsot lefuttatom:

 $ php app/console router:debug  

akkor a routingok közt már látni fogom az admin routingokat is, de ezzel még közel sincs vége a mutatványnak…az app/config/config.yml-ben még definiálnom kell egy service részt:

 services:  
teszt.alma.admin.alma:
class: Teszt\AlmaBundle\Admin\AlmaAdmin
tags:
- { name: sonata.admin, manager_type: orm, group: alma, label: Alma }
arguments: [null, Teszt\AlmaBundle\Entity\Alma, TesztAlmaBundle:AlmaAdmin]

És ezek után semmi nem működött, nem futott le a cache_clear parancs sem, körülbelül fél órás kísérletezgetés után feladtam…

Ezzel a hibaüzenettel nem jutottam dűlőre:

( ! ) Fatal error: Call to undefined method Symfony\Component\DependencyInjection\Definition::replaceArgument() in C:\wamp\www\Symfony2\src\Sonata\AdminBundle\DependencyInjection\AddDependencyCallsPass.php on line 46

Biztos vagyok benne, hogy ha rászánok még 1-2 órát, akkor kibogozhattam volna a hiba okát, de nem volt rá több időm, mert így is az egész tesztre körülbelül egy napom ment rá 🙂 és a végén szinte semmire nem jutottam, mégsem fogok erős hangvételű kritikát megfogalmazni, mert ez az egész még csak béta állapotban lévő projekt, de annyi bizonyos, hogy így nem lesz jó az AdminBundle, legalábbis én így nem fogom szeretni és használni sem az új CRUD és admin generátort, ehelyett működő konzolos parancsok kellenének – pontosan úgy mint az 1.x-es Symfony verziókban, mert ez így eddig visszalépés az előzőekhez képest. Ez szubjektív, én így látom.

Kíváncsian várom a folytatást, remélem 1-2 hónap múlva már használhatóbb lesz az AdminBundle!

This entry was posted in Admin Generator, AdminBundle, Symfony2, Test. Bookmark the permalink.

Leave a comment