CakePHP 3 fixtures not Importing - php

I am using phpunit for testing a CakePHP 3 Controller. The problem is that it does not importing the fixtures. It is just importing live DB data. Reading and writing just uses the LIVE DB even though I have defined a test DB and fixtures. Am I doing something wrong below?
My Fixture
class ToursFixture extends TestFixture {
public $connection = 'test';
public $fields = [
'id' => ['type' => 'integer'],
'title' => ['type' => 'string', 'length' => 255, 'null' => false],
'created' => 'datetime',
'modified' => 'datetime'
'_constraints' => [
'primary' => ['type' => 'primary', 'columns' => ['id']]
]
];
public $records = [
[
'title' => 'tour 1',
'created' => '2015-07-24 09:15:48',
'modified' => '2015-07-24 09:15:48',
],
];
}
My Test Class
namespace App\Test\TestCase\Controller;
use Cake\ORM\TableRegistry;
use Cake\TestSuite\IntegrationTestCase;
use Cake\TestSuite\TestCase;
use App\Controller\ToursController;
use Cake\TestSuite\Fixture\TestFixture;
require '../../bootstrap.php';
class ToursControllerTest extends IntegrationTestCase {
public $fixtures = ['app.tours'];
App Config DB
'test' => [
'className' => 'Cake\Database\Connection',
'driver' => 'Cake\Database\Driver\Mysql',
'persistent' => false,
'host' => 'localhost',

Related

laravel + mongo + gpaphql get children array

i have data in mongodb
it is a road object that has a property and an array of points that it consists of:
my model in laravel
<?php
namespace App\Models;
use App\Traits\Uuids;
use GraphQL\Type\Definition\Type;
use Rebing\GraphQL\Support\Facades\GraphQL;
use Jenssegers\Mongodb\Eloquent\Model as Eloquent;
class Road extends Eloquent
{
//use HasFactory;
use Uuids;
protected $connection = 'mongodb';
protected $collection = 'roads';
protected $fillable = ['id', 'roadId', 'code', 'name', 'points'];
#public $timestamps = false;
public $incrementing = false;
public function fields() : array
{
return [
'id' => [
'type' => Type::string(),
'description' => 'The identifier of the road',
],
'roadId' => [
'type' => Type::nonNull(Type::int()),
'description' => 'ID road of external database',
],
'code' => [
'type' => Type::string(),
'description' => 'code of document',
],
'name' => [
'type' => Type::nonNull(Type::string()),
'description' => 'road name',
],
'points' => [
'name' => 'points',
'description' => 'points of road',
'type' => GraphQL::type('RoadPoints'),
'is_relation' => false
]
];
}
}
here we refer to a new type of "point on the road"
GraphQL type 'RoadPoints':
<?php
namespace App\GraphQL\Types;
use App\Models\Address;
use App\Models\RoadPoints;
use GraphQL\Type\Definition\Type;
use Rebing\GraphQL\Support\Facades\GraphQL;
use Rebing\GraphQL\Support\Type as GraphQLType;
class RoadPointsType extends GraphQLType
{
protected $attributes = [
'name' => 'RoadPoints',
'description' => 'The points is defined by the format GeoJSON Point',
'model' => RoadPoints::class,
];
public function fields(): array
{
return [
'type' => [
'type' => Type::string(),
'description' => 'The format GeoJSON',
],
'pk' => [
'type' => Type::string(),
'description' => 'piket of point',
],
'coordinates' => [
'type' => Type::listOf(GraphQL::type('GeoJSON')),
'description' => 'The partner lat and lng',
]
];
}
}
laravel model of RoadPoints
model RoadPoints class :
<?php
namespace App\Models;
use Jenssegers\Mongodb\Eloquent\Model as Eloquent;
class RoadPoints extends Eloquent
{
protected $fillable = ['type', 'pk', 'coordinates'];
protected $casts = [
'coordinates' => 'array'
];
}
graphql RoadQuery :
<?php
namespace App\GraphQL\Queries;
use App\Models\Road;
use Closure;
use GraphQL\Type\Definition\Type;
use Rebing\GraphQL\Support\Query;
use App\Services\RoadService;
use GraphQL\Type\Definition\ResolveInfo;
use Rebing\GraphQL\Support\Facades\GraphQL;
class RoadQuery extends Query
{
private $roadService;
public function __construct(RoadService $roadService)
{
$this->roadService = $roadService;
}
protected $attributes = [
'name' => 'Road',
'description' => 'Query to Road data and points.'
];
public function type(): Type
{
return Type::listOf(GraphQL::type('Road'));
}
public function args(): array
{
return [
'id' => ['name' => 'id', 'type' => Type::string()],
'roadId' => ['name' => 'roadId', 'type' => Type::int()],
'code' => ['name' => 'code', 'type' => Type::string()],
'name' => ['name' => 'name', 'type' => Type::string()],
'lat' => ['name' => 'lat', 'type' => Type::float()],
'lng' => ['name' => 'lng', 'type' => Type::float()]
];
}
public function resolve($root, $args, $context, ResolveInfo $resolveInfo, Closure $getSelectFields)
{
$fields = $resolveInfo->getFieldSelection($depth = 3);
return $this->roadService->find($args, $fields);
}
}
result:
why pk and coordinates is null ?
Please tell me how to correctly select all objects in the array (points).
error in model
change
'type' => GraphQL::type('RoadPoints'),
to
'type' => Type::listOf(GraphQL::type('RoadPoints')),

ZF2 - How to add a new Form in an existing Controller?

I have a login Form LoginForm.php with its Filter LoginFilter.php, that has a View /login/index.phtml, a Controller LoginController.php, two Factory LoginControllerFactory.php & LoginFormFactory.php and it is called in the config.module.php and works perfect. The Form is correctly displayed.
I have a ViewController.php that has a method idAction that shows a post by its id passed by parameter from the homepage in a View called /view/id.phtml. I want to display this Form I created within this View and I don't know how. First, I created the Form exactly as I created the login Form, but I realized that I already configured my id child-route, inside of view route with a Factory in module.config.php.
Then, I tried to set the form in the idAction method, exactly as I did in indexAction in LoginController.php Controller, but I'm receiving the following error: An exception was raised while creating "Rxe\Factory\ViewController"; no instance returned.
I will now show you what I did to try to display this new Form.
First, the Form itself:
class CommentForm extends Form
{
public function buildForm()
{
$this->setAttribute('method', 'POST');
$this->setAttribute('id', 'add-comment-form');
$this->add(array(
'name' => 'comment',
'type' => 'textarea',
'options' => array(
'label' => 'Category'
),
'attributes' => array(
'class' => 'form-control'
)
));
$this->add(array(
'name' => 'submit',
'type' => 'submit',
'attributes' => array(
'class' => 'btn btn-success',
'value' => 'Comment'
)
));
}
}
Form's CommentFormFactory.php calling its Filter and building the Form:
class CommentFormFactory implements FactoryInterface
{
public function createService(ServiceLocatorInterface $serviceLocator)
{
$form = new CommentForm();
$form->setInputFilter($serviceLocator->get('Rxe\Factory\CommentFilter'));
$form->buildForm();
return $form;
}
}
The ViewControllerFactory.php calling the CommentFormFactory.php, just like in LoginControllerFactory.php:
class ViewControllerFactory implements FactoryInterface
{
public function createService(ServiceLocatorInterface $serviceLocator)
{
$serviceManager = $serviceLocator->getServiceLocator();
$viewController = new ViewController();
$viewController->setPostsTable($serviceManager->get('Rxe\Factory\PostsTable'));
$viewController->setCommentsTable($serviceManager->get('Rxe\Factory\CommentsTable'));
$viewController->setCommentForm($serviceManager->get('Rxe\Factory\CommentForm'));
return $viewController;
}
}
The ViewController.php, calling the form within its idAction's ViewModel:
class ViewController extends AbstractActionController
{
use PostsTableTrait;
use CommentsTableTrait;
private $commentForm;
function setCommentForm($commentForm)
{
$this->commentForm = $commentForm;
}
public function indexAction()
{
$category = $this->params()->fromRoute('category');
return new ViewModel(array(
'posts' => $this->postsTable->getPostsByCategory($category),
'categories' => $category
));
}
public function idAction()
{
$id = $this->params()->fromRoute('id');
$viewModel = new ViewModel(array(
'commentForm' => $this->commentForm,
'commentParams' => $this->params()->fromPost(),
'messages' => $this->flashMessenger()->getMessages(),
'posts' => $this->postsTable->getPostById($id),
'posts' => $this->commentsTable->getNumberOfCommentsByPost($id),
'comments' => $this->commentsTable->getCommentsByPost($id)
));
$viewModel->setTemplate('rxe/view/id.phtml');
if ($this->getRequest()->isPost()) {
$this->commentForm->setData($this->params()->fromPost());
if ($this->commentForm->isValid()) {
$this->flashMessenger()->addMessage('Thank you for your comment. :)');
} else {
$this->flashMessenger()->addMessage('Your comment wasn\'t sent.');
}
}
return $viewModel;
}
}
And finally my module.config.php
'controllers' => array(
'invokables' => array(
'Rxe\Controller\Index' => 'Rxe\Controller\IndexController',
'Rxe\Controller\View' => 'Rxe\Controller\ViewController',
'Rxe\Controller\Login' => 'Rxe\Controller\LoginController'
),
'factories' => array(
'Rxe\Factory\LoginController' => 'Rxe\Factory\LoginControllerFactory',
'Rxe\Factory\ViewController' => 'Rxe\Factory\ViewControllerFactory',
'Rxe\Factory\IndexController' => 'Rxe\Factory\IndexControllerFactory'
)
),
'service_manager' => array(
'factories' => array(
'Rxe\Factory\LoginForm' => 'Rxe\Factory\LoginFormFactory',
'Rxe\Factory\LoginFilter' => 'Rxe\Factory\LoginFilterFactory',
'Rxe\Factory\CommentForm' => 'Rxe\Factory\CommentFormFactory',
'Rxe\Factory\CommentFilter' => 'Rxe\Factory\CommentFilterFactory',
'Rxe\Factory\PostsTable' => 'Rxe\Factory\PostsTableFactory',
'Rxe\Factory\CategoriesTable' => 'Rxe\Factory\CategoriesTableFactory',
'Rxe\Factory\CommentsTable' => 'Rxe\Factory\CommentsTableFactory',
'Zend\Db\Adapter\AdapterService' => 'Zend\Db\Adapter\AdapterServiceFactory'
)
),
Please, let me know if you need me to show you more codes. Thank you in advance.
EDIT #1
If I remove the line that calls the Form in the ViewControllerFactory.php, I get the following error: Fatal error: Call to a member function prepare() on a non-object in /home/vol12_3/byethost4.com/b4_16354889/htdocs/module/Rxe/view/rxe/view/id.phtml on line 31
The id.phtml is:
<!-- Comment form -->
<div id="comment-form-area" class="col-xs-3">
<?php $this->commentForm->prepare() ?>
<?php echo $this->form()->openTag($this->commentForm); ?>
<div class="form-group comment-area">
<?php echo $this->formRow($this->commentForm->get('comment_content')); ?>
</div>
<div class="form-group">
<?php echo $this->formRow($this->commentForm->get('submit')); ?>
</div>
<?php echo $this->form()->closeTag(); ?>
</div>
<!-- /Comment form -->
Try removing these lines
'invokables' => array(
'Rxe\Controller\Index' => 'Rxe\Controller\IndexController',
'Rxe\Controller\View' => 'Rxe\Controller\ViewController',
'Rxe\Controller\Login' => 'Rxe\Controller\LoginController'
),
If it doesn't work, have a look at this tutorial how to create proper controller factories and pass dependencies. https://samsonasik.wordpress.com/2015/03/31/zend-framework-2-using-__invokepluginmanager-manager-in-services-factory/
An example how I build my forms:
namespace Admin\Form;
use Zend\Form\Form;
use Zend\InputFilter\InputFilterProviderInterface;
class ContentForm extends Form implements InputFilterProviderInterface
{
public function __construct()
{
parent::__construct("content");
}
public function init()
{
$this->setAttribute('method', 'post');
$this->add([
'type' => 'Zend\Form\Element\Text',
'name' => 'title',
'attributes' => [
'required' => true,
'size' => 40,
'id' => "seo-caption",
'placeholder' => 'Title',
],
'options' => [
'label' => 'Title',
],
]);
$this->add([
'type' => 'Zend\Form\Element\Text',
'name' => 'text',
'attributes' => [
'class' => 'ckeditor',
'rows' => 5,
'cols' => 80,
],
'options' => [
'label' => 'Text',
],
]);
}
public function getInputFilterSpecification()
{
return [
[
"name"=>"title",
"required" => true,
'filters' => [
['name' => 'StripTags'],
['name' => 'StringTrim'],
],
'validators' => [
['name' => 'NotEmpty'],
[
'name' => 'StringLength',
'options' => [
'encoding' => 'UTF-8',
'min' => 1,
'max' => 200,
],
],
],
],
[
"name"=>"text",
"required" => true,
'filters' => [
['name' => 'StripTags'],
['name' => 'StringTrim'],
],
'validators' => [
['name' => 'NotEmpty'],
[
'name' => 'StringLength',
'options' => [
'encoding' => 'UTF-8',
'min' => 1,
],
],
],
],
];
}
}
Than I create a Factory
namespace Admin\Factory\Controller;
use Admin\Controller\ContentController;
use Zend\Mvc\Controller\ControllerManager;
class ContentFormFactory
{
/**
* #{inheritDoc}
*/
public function __invoke(ControllerManager $controllerManager)
{
return new ContentController(
$controllerManager->getServiceLocator()->get('FormElementManager')->get('Admin\Form\ContentForm')
);
}
}
Inside module.config.php I have this code
'controllers' => [
'factories' => [
'Admin\Controller\Content' => "Admin\Factory\Controller\ContentFormFactory",
],
'invokables' => [
...
],
],
Please, show us some more code.

Add custom RBAC rule to PhpManager in Yii 2.0

I want to add a custom rule to PhpManager RBAC in Yii 2.0.
Here is the custom rule (#app/rbac/OwnerRule.php):
<?php
namespace app\rbac;
use yii\rbac\Rule;
/**
* Checks if userID matches user passed via params
*/
class OwnerRule extends Rule
{
public $name = 'isOwner';
public function execute($user, $item, $params)
{
$access = false;
if(isset($params['id'])){
// My custom logic used to set $access
}
return $access;
}
}
Here is the RBAC hierarchy file (#app/data/rbac.php)
<?php
use yii\rbac\Item;
return [
'manageThing0' => ['type' => Item::TYPE_OPERATION, 'description' => '...', 'bizRule' => NULL, 'data' => NULL],
'manageThing1' => ['type' => Item::TYPE_OPERATION, 'description' => '...', 'bizRule' => NULL, 'data' => NULL],
'manageThing2' => ['type' => Item::TYPE_OPERATION, 'description' => '...', 'bizRule' => NULL, 'data' => NULL],
// AND THE ROLES
'guest' => [
'type' => Item::TYPE_ROLE,
'description' => 'Guest',
'bizRule' => NULL,
'data' => NULL
],
'user' => [
'type' => Item::TYPE_ROLE,
'description' => 'User',
'children' => [
'guest',
'manageThing0', // User can edit thing0
],
'bizRule' => 'return !Yii::$app->user->isGuest;',
'data' => NULL
],
'moderator' => [
'type' => Item::TYPE_ROLE,
'description' => 'Moderator',
'children' => [
'user', // Can manage all that user can
'manageThing1', // and also thing1
],
'bizRule' => NULL,
'data' => NULL
],
'admin' => [
'type' => Item::TYPE_ROLE,
'description' => 'Admin',
'children' => [
'moderator', // can do all the stuff that moderator can
'manageThing2', // and also manage thing2
],
'bizRule' => NULL,
'data' => NULL
],
];
How do I use my custom rule in the hierarchy file?
See these links hope you will find what you are looking for,
http://www.yiiframework.com/doc-2.0/guide-security-authorization.html
http://yii2-user.dmeroff.ru/docs/custom-access-control
RBAC for basic yii2 template

Secondary database connection with Doctrine 2 and ZF2

I am trying to add a extra connection to my doctrine configuration. my orm_default connection works perfectly fine, and now I'm trying to add a new module with its own Doctrine configuration (mostly learning purposes, buts its rather annoying that I can't get it to work).
The module is called Frontpage, and all relevant code is in this one, except for username/password details that resides in local.php...
My error is
Zend\ServiceManager\Exception\ServiceNotCreatedException
An exception was raised while creating "doctrine.entitymanager.orm_hosts"; no instance returned
Also further down the stacktrace (the last exception) which I think is relevant, but don't know how to fix...
Zend\Stdlib\Exception\BadMethodCallException
The option "hydration_cache" does not have a matching setHydrationCache setter method which must be defined
Here is my module config (relevant parts) file:
'doctrine' => [
'connection' => [
'orm_hosts' => [
'driverClass' => 'Doctrine\DBAL\Driver\PDOMySql\Driver',
'params' => [
'host' => '127.0.0.1',
'port' => '3306',
'dbname' => 'hosts',
],
],
],
'entitymanager' => array(
'orm_hosts' => array(
'connection' => 'orm_hosts',
'configuration' => 'orm_hosts'
)
),
'configuration' => array(
'orm_hosts' => array(
'driver' => 'orm_hosts',
'generate_proxies' => true,
'proxy_dir' => 'data/DoctrineORMModule/Proxy',
'proxy_namespace' => 'DoctrineORMModule\Proxy',
'filters' => array(),
'metadata_cache' => 'array',
'query_cache' => 'array',
'result_cache' => 'array',
//'hydration_cache' => 'array',
)
),
'driver' => array(
'orm_hosts' => array(
'class' => 'Doctrine\ORM\Mapping\Driver\DriverChain',
'drivers' => array(
'Common\Entity' => 'Hosts_Driver'
)
),
'Hosts_Driver' => array(
'class' => 'Doctrine\ORM\Mapping\Driver\AnnotationDriver',
'cache' => 'array',
'paths' => array(
__DIR__ . '/../src/Common/Entity'
)
),
),
'eventmanager' => array(
'orm_hosts' => array()
),
'sql_logger_collector' => array(
'orm_hosts' => array(),
),
'entity_resolver' => array(
'orm_hosts' => array()
),
],
And my Module.php's getServiceConfig():
public function getServiceConfig()
{
return array(
'factories' => array(
'doctrine.connection.orm_hosts' => new Service\DBALConnectionFactory('orm_hosts'),
'doctrine.configuration.orm_hosts' => new Service\ConfigurationFactory('orm_hosts'),
'doctrine.entitymanager.orm_hosts' => new Service\EntityManagerFactory('orm_hosts'),
'doctrine.entity_resolver.orm_hosts' => new Service\EntityResolverFactory('orm_hosts'),
'doctrine.sql_logger_collector.orm_hosts' => new Service\SQLLoggerCollectorFactory('orm_hosts'),
'doctrine.driver.orm_hosts' => new \DoctrineModule\Service\DriverFactory('orm_hosts'),
'doctrine.eventmanager.orm_hosts' => new \DoctrineModule\Service\EventManagerFactory('orm_hosts'),
'DoctrineORMModule\Form\Annotation\AnnotationBuilder\orm_hosts' => function(\Zend\ServiceManager\ServiceLocatorInterface $sl) {
return new \DoctrineORMModule\Form\Annotation\AnnotationBuilder($sl->get('doctrine.entitymanager.orm_hosts'));
},
),
);
}
And here is my getEntityManager() in IndexController that fails
/**
* #return array|EntityManager|object
*/
public function getEntityManager() {
if (NULL === $this->em) {
/** #var \Doctrine\ORM\EntityManager $em */
$em = $this->getServiceLocator()->get('doctrine.entitymanager.orm_hosts');
//$em = $this->getServiceLocator()->get('doctrine')->getManager("orm_hosts");
$this->em = $em;
}
return $this->em;
}
Any help will be gratly appreciated :)
Best regards
Richard
Okay, so I still don't know what is wrong with the above code, but if I remove
'Hydration_cache' => 'array'
In the doctrine configuration from my module config, it actually works! Still, if anyone want's to explain what happens, I would appreciate to know more :)

Pagination in CakePHP 3.0

I have been playing with the developer preview version of CakePHP 3.0 and I'm stuck trying to get the new ORM working with pagination.
In my PostsController.php I have:
<?php
namespace App\Controller;
use App\Controller\AppController;
class PostsController extends AppController {
public $name = 'Posts';
public $uses = 'Posts';
public $components = ['Paginator'];
public $paginate = [
'fields' => ['Posts.id'],
'limit' => 1,
'order' => [
'Post.id' => 'asc'
]
];
public function index() {
$posts = $this->paginate('Posts');
$this->set('posts', $posts);
}
}
However the paging is working but the data doesn't come back. Apparently this because the data isn't directly returned in the new ORM but an object... Has anyone tried this yet? Knows how to fix the issue to get it working with the paginator?
I've been reading the Migration Guide: http://book.cakephp.org/3.0/en/appendices/orm-migration.html but don't see anything about combining it with the paginator.
Note: I can't debug $posts and show it here because it's about 2000 lines of code containing all sorts of stuff about the ORM. Here's a taster...
object(Cake\ORM\ResultSet) {
[protected] _query => object(Cake\ORM\Query) {
[protected] _table => object(Cake\ORM\Table) {
[protected] _table => 'posts'
[protected] _alias => 'Posts'
[protected] _connection => object(Cake\Database\Connection) {
[protected] _config => array(
'password' => '*****',
'login' => '*****',
'host' => '*****',
'database' => '*****',
'prefix' => '*****',
'persistent' => false,
'encoding' => 'utf8',
'name' => 'default',
'datasource' => object(Cake\Database\Driver\Mysql) {
[protected] _baseConfig => array(
'password' => '*****',
'login' => '*****',
'host' => '*****',
'database' => '*****',
'port' => '*****',
'persistent' => true,
'flags' => array(),
'encoding' => 'utf8',
'timezone' => null,
'init' => array(),
'dsn' => null
)
[protected] _config => array(
'password' => '*****',
'login' => '*****',
'host' => '*****',
'database' => '*****',
'port' => '*****',
'prefix' => '*****',
'persistent' => false,
'encoding' => 'utf8',
'name' => 'default',
'flags' => array(),
'timezone' => null,
'init' => array(),
'dsn' => null
)
[protected] _autoQuoting => false...
So as you can see it's a huge object and presumably the data is somewhere within it.
Apparently this because the data isn't directly returned in the new
ORM but an object...
It's not a bug it's a feature. ;) CakePHP3 returns a ResultSet object as you can see and entity objects for records. You'll have to work with these objects now instead of arrays.
I wounder if you really read the migration guide you've linked because it is all in there:
Cake\ORM\ResultSet - A collection of results that gives powerful tools for manipulating data in aggregate.
Cake\ORM\Entity - Represents a single row result. Makes accessing data and serializing to various formats a snap.
Further down on that page there is even more info about that. Take a look at the ResultSet API. You'll see that it implements Iterator, you can use it like an array:
Controller method:
public function index() {
$this->set('users', $this->Paginator->paginate($this->Users, [
'limit' => 5,
'conditions' => [
'Users.active' => 1
]
]));
}
There is a lot of documentation to read in the doc block of the paginate() method.
View index.ctp:
foreach ($users as $user) {
debug($user);
}
This will show you Entity objects. I'm not pasting the whole long debug output here, just a part of it.
object(Cake\ORM\Entity) {
[protected] _properties => array(
'password' => '*****',
'id' => '52892217-91ec-4e5d-a9f4-1b6cc0a8000a',
'username' => 'burzum',
'slug' => '',
// ...
To get something from the object back just do this:
echo $user->username;
The actual data is in the protected property Entity::$_properties and accessed by __get.
This will be in your controller.
public function index() {
$this->set('users', $this->paginate($this->Users));
$this->set('_serialize', ['users'])
}
This you can put in your action
Paginatore logic

Categories