Create Podio App Workflows using API - PHP - podio

I'm using Flows API to create new workflows.
API: https://developers.podio.com/doc/flows/add-new-flow-26309928
I've prepared the attributes properly (by referring the API documentation). It is not working as expected and returning an error while creating flows with effects. I was able to create a flow without any effects, ie. a null flow which does nothing. But when I tried to create flow with effects, it shows error as below.
PodioServerError: An unexpected error occurred during execution.
Below given is my code part,
$attributes = array(
'config' => array(
'conditions' => array()
),
"effects" => array(array(
"values" => array(
'attribute_id' => "comment.value",
'label' => "Comment",
'required' => true,
'substitutions' => array(),
'type' => "text",
'value' => "This is a test comment from flow"
),
'type' => "comment.create",
)),
'name' => 'Test Flow via API',
'type' => 'item.create'
);
PodioFlow::create('app', $appID, $attrib);
Any idea what could be the error or how to properly debug this?

Can you please try:
$attributes = array(
'config' => array(
'conditions' => array()
),
"effects" => array(array(
"attributes" => array(array(
'attribute_id' => "comment.value",
'label' => "Comment",
'required' => true,
'substitutions' => array(),
'type' => "text",
'value' => "This is a test comment from flow"
)),
'type' => "comment.create",
)),
'name' => 'Test Flow via API',
'type' => 'item.create'
);
The only difference is values were replaced with attributes inside effects. That was mistype in docs, sorry, it's fixed now.

Related

F3 Cortex and Many to Many relation

I'm building a simple app using F3 and Cortex but I'm running in some problems trying to create a simple Many to Many relation. Its just two tables (and a third, from the relation), the tables already exist and have some data:
class User extends \DB\Cortex {
protected
$fieldConf = array(
'name' => array (
'type' => 'VARCHAR128',
'nullable' => false,
'required' => true,
),
'email' => array (
'type' => 'VARCHAR256',
'nullable' => false,
'required' => true,
),
'password' => array (
'type' => 'VARCHAR128',
'nullable' => false,
'required' => true,
),
// 'groups' => array(
// 'has-many' => array('Group', 'group_id', 'user_has_group')
// )
),
$db = 'db',
$table = 'user';
}
and
class Group extends \DB\Cortex {
protected
$fieldConf = array(
'name' => array(
'type' => 'VARCHAR128',
'nullable' => false,
'required' => true,
),
'description' => array(
'type' => 'VARCHAR128',
'nullable' => false,
'required' => true,
),
// 'users' => array(
// 'has-many' => array('User', 'user_id', 'user_has_group')
// )
),
$db = 'db',
$table = 'group';
}
accourind with this model of the database
But if I remove those comment marks, I get a strange error while acessing anything:
Internal Server Error
No valid DB Connection given.
And on refresh:
Internal Server Error
Fatal error: Leaked 1 hashtable iterators
It looks silly, but I searched all over and spent the better part of a whole day, and still can't seem to make it work.

Yii, CGridView not showing records of a certain attribute

So I have created records and each has their own particular Service field. They are all filled up (not null).
In the MySQL database, there are also records of that field Service
But in my CGridView, my Service field is all blank. All the Service fields are blank for all the records. When I click on the button View - The one with the magnifying glass, it says Service - Not Set
Can I know what may cause the problem? Please help me Thanks!
UPDATED WITH CGRIDVIEW CODE
<?php $this->widget('zii.widgets.grid.CGridView', array(
'id' => 'booking-grid',
'htmlOptions'=>array('class'=>'grid-view grid-size'),
'dataProvider' => $model->search(),
'filter' => $model,
'columns' => array(
array(
'name'=>'date',
'htmlOptions'=>array('style'=>'text-align:center', 'height'=>'50px', 'width'=>'80px'),
'headerHtmlOptions'=>array('height'=>'30px'),
),
array(
'name'=>'timeStart',
'header'=>"Time",
'htmlOptions'=>array('style'=>'text-align:center', 'width'=>'80px'),
),
array(
'name'=>'client_id',
'value'=>'GxHtml::valueEx($data->client)',
'filter'=>GxHtml::listDataEx(Client::model()->findAllAttributes(null, true)),
'htmlOptions'=>array('width'=>'200px'),
),
array(
'name'=>'service_id',
'value'=>'GxHtml::valueEx($data->service)',
'filter'=>GxHtml::listDataEx(Service::model()->findAllAttributes(null, true)),
),
array(
'name' => 'complete',
'header'=>'Status',
'value' => '($data->complete == 0) ? Yii::t(\'app\', \'Open\') : Yii::t(\'app\', \'Close\')',
'filter' => array('0' => Yii::t('app', 'Open'), '1' => Yii::t('app', 'Close')),
'htmlOptions'=>array('width'=>'60px', 'style'=>'text-align:center'),
),
'remarks',
array(
'class' => 'CButtonColumn',
'visible'=>true,
'htmlOptions'=>array('width'=>'70px'),
'template' => '{view}{update}{delete}{changeComplete}',
'buttons'=>array(
'view' => array(
'visible'=>"true",
),
'update' => array(
'visible'=>"true",
),
'delete' => array(
'visible'=>"UserIdentity::isRoleMember('Admin')",
),
'changeComplete' => array(
'visible' => '$data->complete=="0"',
'imageUrl' => 'images/complete.png',
'options' => array(
'title' => 'Complete',
),
'url' => 'Yii::app()->createUrl("booking/changeComplete", array("id"=>$data->id))',
'click' => "function(){
$.fn.yiiGridView.update(\"booking-grid\", {
type:'POST',
url:$(this).attr('href'),
success:function(data) {
$.fn.yiiGridView.update(\"booking-grid\");
}
})
return false;
}",
),
),
),
))); ?>
I have tried looking at other CGridViews with the same field, they look the same and they're working perfectly fine.
I think the problem is $data->service. Probably your data has a relation with the Service entity. So for accessing attributes of Service you should use $data->service->attributeName.

Change imageUrl with user_status field in user table

I have to model: User, UserFlag
In User/index added a column in CGridView:
array(
'class' => 'CButtonColumn',
'htmlOptions' => array("style" => 'width: 45px;'),
'template' => '{enable}',
'header' => 'management',
'buttons' => array(
'enable' => array(
'name' => 'enable',
'imageUrl' => Yii::app()->baseUrl."/images/ico/group.png",
'url' => '"#".$data->username',
'click' => 'js:function() {
if(confirm("Are you sure?")){
changeUserStatus($(this).attr("href").replace("#", ""));
}
}',
),
),
I will read user status from UserFlag Model and if status is active I show 1.png and if status is deactive I show 2.png.
Yeah, the $data var isn't accessible from imageUrl unfortunately. I would recommend extending from CButtonColumn like Stu's link suggested.
If you don't want to do that you could create two button columns and show them depending on the status. It would be something like this but you may need to adjust it if your active user_status value isn't 1 or you want the images reversed:
'enable' => array(
'name' => 'enable',
'visible'=>'$data->user_status == 1'
'imageUrl' => Yii::app()->baseUrl."/images/ico/1.png",
'url' => '"#".$data->username',
'click' => 'js:function() {
if(confirm("Are you sure?")){
changeUserStatus($(this).attr("href").replace("#", ""));
}
}',
),
'disable' => array(
'name' => 'disable',
'visible'=>'$data->user_status == 0'
'imageUrl' => Yii::app()->baseUrl."/images/ico/0.png",
'url' => '"#".$data->username',
'click' => 'js:function() {
if(confirm("Are you sure?")){
changeUserStatus($(this).attr("href").replace("#", ""));
}
}',
),
You would also need to add {disable} to your CButtonColumn template.
It's not ideal since you're repeating code, but at least you can do it without having to extend any classes.

ZF2: create url aliases in router

I'm new to Zend Framework 2 and i want to learn this framework. I want to create url aliases in router.
For example, I have defined something like this in module.config.php
'router' => array(
'routes' => array(
'home' => array(
'type' => 'Zend\Mvc\Router\Http\Literal',
'options' => array(
'route' => '/',
'defaults' => array(
'controller' => 'Application\Controller\Index',
'action' => 'index',
),
),
),
'node' => array(
'type' => 'Application\Controller\AliasSegment',
'options' => array(
'route' => '/node[/:id]',
'constraints' => array(
'id' => '[0-9]+'
),
'defaults' => array(
'__NAMESPACE__' => 'Application\Controller',
'controller' => 'Index',
'action' => 'index',
'id' => '0'
),
),
'may_terminate' => true,
),
),
),
When i type www.myapp.local/node/1 it routes to the default action in default controller of my application. What i want is a router extension that can handle aliases for url paths. For example:
www.myapp.local/node/1 = www.myapp.local/aboutus
www.myapp.local/node/2 = www.myapp.local/company/gallery
I know that it was possible in ZF. Here is a link to tutorial how to achieve this in ZF:
friendly urls
I know that this is in Polish but code is self-explanatory i think :)
The idea is to use url helper to assembly valid url using aliases or normal segments (node/[:id])
I've already created AliasSegment class in my Application\Controller folder but it shows me an error:
Fatal error: Uncaught exception 'Zend\ServiceManager\Exception\ServiceNotFoundException' with message 'Zend\ServiceManager\ServiceManager::get was unable to fetch or create an instance for Application\Controller\AliasSegment' in C:\xampp\htdocs\industengine\vendor\zendframework\zendframework\library\Zend\ServiceManager\ServiceManager.php:450 Stack trace: #0
My AliasSegment class (incomplete):
<?php
namespace Zend\Mvc\Router\Http;
use Traversable;
use Zend\Mvc\Router\Exception;
use Zend\Stdlib\ArrayUtils;
use Zend\Stdlib\RequestInterface as Request;
class AliasSegment extends Segment
{
public function match(Request $request, $pathOffset = null)
{
}
}
I was looking for an answer for hours and i couldnt find anything. Please tell me at least what I'm doing wrong, where to insert a code or maybe You know better sollution?
I'm not looking for ready application. I want to learn something but i would appreciate if You can tell me an answer in details :)
Thanks in advance and sorry for my English :)
EDITED:
My custom router is working now. At this moment aliases are hardcoded but it works.
My AliasSegment class looks now:
<?php
namespace Application\Controller;
use Traversable;
use Zend\Mvc\Router\Exception;
use Zend\Stdlib\ArrayUtils;
use Zend\Stdlib\RequestInterface as Request;
use Zend\Mvc\Router\Http;
class AliasSegment extends \Zend\Mvc\Router\Http\Segment
{
public function match(Request $request, $pathOffset = null)
{
$uri = $request->getUri();
$path = $uri->getPath();
//sample logic here
//for /about/gallery uri set node id to 1
//todo: get action, controller and module from navigation
if($path == '/about/gallery'){
$uri->setPath('/node/1');
$request->setUri($uri);
}
return parent::match($request, $pathOffset);
}
protected function buildPath(array $parts, array $mergedParams, $isOptional, $hasChild)
{
if(isset($mergedParams['link'])){
return $mergedParams['link'];
}
return parent::buildPath($parts, $mergedParams, $isOptional, $hasChild);
}
}
In this case /about/gallery is an alias to /node/1. Both adresses are correct. The buildPath function returns alias path correctly. Well, I hope this would be usefull for somebody :)
However i want to setup it in Zend_Navigation with additional parameter named 'link'.
I've done 50% of what i want to achieve however now I have problem to get Zend_Navigation from my router. I don't know how to pass it. I guess it should be something like this:
$sm = $this->getServiceLocator();
$auth = $sm->get('Navigation');
It works in my IndexController but doesnt work in my AliasSegment. I need to find in navigation array nodes with 'link' parameter.
EDIT
I've found solution. The answer is below.
unable to fetch or create an instance for Application\Controller\AliasSegment
if this is controller then I would expect in module.config.php to have:
'controllers' => array(
'invokables' => array(
'\Application\Controller\AliasSegment' => '\Application\Controller\AliasSegment',
)
),
also namespace of your class looks a bit weird:
namespace Zend\Mvc\Router\Http;
what about:
namespace Application\Controller;
OK, I've made it. The important thing for this Thread:
ZF2: How to get Zend\Navigation inside custom route?.
You can use any segment type route. But this may need a little modifications to match function.
If navigation's single page will have 'link' param, the url will be converted to 'link' string but other params will stay behind it. Just think of it as an overlay for default URI of current route.
I had to modify my custom route class a little bit. First of all, i had to change its namespace to Application\Router. Here is a full class:
// EDIT - file within ModuleName/src/Router/Alias.php
namespace Application\Router;
use Traversable;
use Zend\Mvc\Router\Exception;
use Zend\Stdlib\ArrayUtils;
use Zend\Stdlib\RequestInterface as Request;
use Zend\Mvc\Router\Http;
class Alias extends Http\Segment
{
private static $_navigation = null;
public function match(Request $request, $pathOffset = null)
{
$uri = $request->getUri();
$path = $uri->getPath();
$items = self::$_navigation->findAllBy('route', 'node');
$params = null;
if($items != null){
$t = sizeof($items);
for ($i=0; $i < $t; $i++) {
$item = $items[$i];
$params = $item->getParams();
if (isset($params['link']) && $params['link']==$path){
$uri->setPath('/'.$item->getRoute().'/'.$params['id']);
$request->setUri($uri);
break;
}
}
}
return parent::match($request, $pathOffset);
}
public function setNavigation($navigation){
self::$_navigation = $navigation;
}
protected function buildPath(array $parts,
array $mergedParams, $isOptional, $hasChild)
{
if(isset($mergedParams['link'])){
return $mergedParams['link'];
}
return parent::buildPath($parts, $mergedParams,
$isOptional, $hasChild);
}
}
here is sample part of module.config.php:
'navigation' => array(
// The DefaultNavigationFactory we configured in (1) uses 'default' as the sitemap key
'default' => array(
// And finally, here is where we define our page hierarchy
'account' => array(
'label' => 'Account',
'route' => 'node',
'params' => array(
'id' => '2',
),
'pages' => array(
'home' => array(
'label' => 'Dashboard',
'route' => 'node',
'params' => array(
'id' => '8',
'link' => '/about/gallery'
),
),
'login' => array(
'label' => 'Sign In',
'route' => 'node',
'params' => array(
'id' => '6',
'link' => '/signin'
),
),
'logout' => array(
'label' => 'Sign Out',
'route' => 'node',
'params' => array(
'id' => '3',
),
),
),
),
),
),
'router' => array(
'routes' => array(
'home' => array(
'type' => 'Zend\Mvc\Router\Http\Literal',
'options' => array(
'route' => '/',
'defaults' => array(
'controller' => 'Application\Controller\Index',
'action' => 'index',
),
),
),
'node' => array(
'type' => 'Application\Router\Alias',
'options' => array(
'route' => '/node[/:id]',
'constraints' => array(
'id' => '[0-9]+'
),
'defaults' => array(
'__NAMESPACE__' => 'Application\Controller',
'controller' => 'Index',
'action' => 'index',
'id' => '0'
),
),
'may_terminate' => true,
),
),
),
If it is just for routes like /about and /about/galery then you can simply use literal routes with child routes
'about' => array(
'type' => 'literal',
'options' => array(
'route' => '/about',
'defaults' => array(
'controller' => 'module-controller-about',
'action' => 'index'
)
),
'may_terminate' => true,
'child_routes' => array(
'galery' => array(
'type' => 'literal',
'options' => array(
'route' => '/galery',
'defaults' => array(
'controller' => 'module-controller-galery'
)
)
)
)
)
When it comes to URLs like /blog/1-my-great-seo-title you probably have to set-up a Regex route (which is the slowest, literals are fastest).
Maybe check out DASPRiDs Slides from his Router Presentation

ZF2 Select element usage

I'm using Zend Framework 2 and I need a Dependent Dropdown. When user select an category (cat_id on my example) the system fills the subcategory (sca_id) with the correct elements.
I could do that by creating an application like this:
My form looks like:
$this->add(array(
'name' => 'cat_id',
'type' => 'Zend\Form\Element\Select',
'options' => array(
'label' => 'Categoria',
'value_options' => array(
'' => '',
),
),
));
$this->add(array(
'name' => 'sca_id',
'type' => 'Zend\Form\Element\Select',
'options' => array(
'label' => 'Sub Categoria',
'style' => 'display:none;', // Esse campo soh eh exibido qndo uma categoria for escolhida
'value_options' => array(
'' => '',
),
),
));
Note that I don't fill the value_options there, because I choose do that in my controller, where the Service Manager is avaliable:
$form = new ProdutoForm('frm');
$form->setAttribute('action', $this->url()->fromRoute('catalogo-admin', array( ... )));
// Alimenta as comboboxes...
$form->get('cat_id')->setValueOptions($this->getCategoriaService()->listarCategoriasSelect());
On the change event of cat_id I do an $.ajax to grab the elements from an Action and fill the sca_id.
That works fine!
The problem is on my validation:
$this->add(array(
'name' => 'cat_id',
'require' => true,
'filters' => array(
array('name' => 'Int'),
),
));
$this->add(array(
'name' => 'sca_id',
'require' => true,
'filters' => array(
array('name' => 'Int'),
),
));
When I submit my form it keeps saying : The input was not found in the haystack for both dropdowns...
What I'm doing wrong?
Extra questions : There's a better way to fill my dropdowns?
Ps.: I guess this question Disable notInArray Validator Zend Framework 2 asks something similar than me, but I wanted to detail more my problem.
Well, I realized that I should populate my select element before validate my form!
// SaveAction
$request = $this->getRequest();
if ($request->isPost())
{
$form = new ProdutoForm();
// Alimenta as comboboxes...
$form->get('cat_id')->setValueOptions($this->getCategoriaService()->listarCategoriasSelect());
$form->get('sca_id')->setValueOptions($this->getSubCategoriaService()->listarSubCategoriasSelect());
// If the form doesn't define an input filter by default, inject one.
$form->setInputFilter(new ProdutoFormFilter());
// Get the data.
$form->setData($request->getPost());
// Validate the form
if ($form->isValid())
{
// Valid!
}else{
// Invalid...
}
That code works nice. My form now validate perfectly!