In ZF2, I have a custom form element factory. It creates a custom MultiCheckbox and fills the checkbox values and labels from a db query.
class MyMultiCheckboxFactory
{
public function __invoke(FormElementManager $formElementManager)
{
$multiCheck = new \Zend\Form\Element\MultiCheckbox();
$serviceManager = $formElementManager->getServiceLocator();
$mapper = $serviceManager->get('Path\To\Mapper\To\Query\DB');
$descriptions = $mapper->findDescriptions($id);
// some processing to prepare $value_options array
$multiCheck->setOptions([
'label' => 'blah-blah',
'value_options' => $value_options
]);
return $multiCheck;
}
}
My problem is as follows. The method findDescriptions($id) depends on the $id which I can get from the route. But when I use MyMultiCheckbox in the form like this:
public function init()
{
$this->add([
'type' => 'Path\To\MyMultiCheckbox',
'name' => 'someName'
]);
}
I don't know how to pass the $id into the MyMultiCheckbox.
Could anyone help pleeeeeeeeeease?
You can fetch the id via the 'route match' instance inside the factory.
$event = $serviceManager->get('Application')->getMvcEvent();
$id = $event->getRouteMatch()->getParam('id', false);
if (empty($id)) {
throw new ServiceNotCreatedException('id not set!');
}
$descriptions = $mapper->findDescriptions($id);
Related
I want to add unique Elements in a Zend Form Collection.
I found this awesome work from Aron Kerr
I do the forms and fieldsets like in Aron Kerr´s Example and it works fine.
In my case i create a Form to insert a collection of stores from a company.
My Form
First of all i have a Application\Form\CompanyStoreForm with a StoreFieldset like this:
$this->add(array(
'name' => 'company',
'type' => 'Application\Form\Stores\CompanyStoresFieldset',
));
The Fieldsets
Application\Form\Stores\CompanyStoresFieldset has a Collection of Store Entities like this:
$this->add(array(
'type' => 'Zend\Form\Element\Collection',
'name' => 'stores',
'options' => array(
'target_element' => array(
'type' => 'Application\Form\Fieldset\StoreEntityFieldset',
),
),
));
Application\Form\Fieldset\StoreEntityFieldset
$this->add(array(
'name' => 'storeName',
'attributes' => ...,
'options' => ...,
));
//AddressFieldset
$this->add(array(
'name' => 'address',
'type' => 'Application\Form\Fieldset\AddressFieldset',
));
The difference to Arron Kerrs CategoryFieldset is I adding one more fieldset: Application\Form\Fieldset\AddressFieldset
Application\Form\Fieldset\AddressFieldset has a text-element streetName.
The Inputfilters
The CompanyStoresFieldsetInputFilter has no elements to validate.
The StoreEntityFieldsetInputFilter has validators for storeName and the Application\Form\Fieldset\AddressFieldset like this
public function __construct() {
$factory = new InputFactory();
$this->add($factory->createInput([
'name' => 'storeName',
'required' => true,
'filters' => array( ....
),
'validators' => array(...
),
]));
$this->add(new AddressFieldsetInputFilter(), 'address');
}
The AddressFieldset has another Inputfilter AddressFieldsetInputFilter.
In AddressFieldsetInputFilter I adding a InputFilter for streetName.
FormFactory
Adding all Inputfilters to the Form like this
public function createService(ServiceLocatorInterface $serviceLocator) {
$form = $serviceLocator->get('FormElementManager')->get('Application\Form\CompanyStoreForm');
//Create a Form Inputfilter
$formFilter = new InputFilter();
//Create Inputfilter for CompanyStoresFieldsetInputFilter()
$formFilter->add(new CompanyStoresFieldsetInputFilter(), 'company');
//Create Inputfilter for StoreEntityFieldsetInputFilter()
$storeInputFilter = new CollectionInputFilter();
$storeInputFilter->setInputFilter(new StoreEntityFieldsetInputFilter());
$storeInputFilter->setUniqueFields(array('storeName'));
$storeInputFilter->setMessage('Just insert one entry with this store name.');
$formFilter->get('company')->add($storeInputFilter, 'stores');
$form->setInputFilter($formFilter);
return $form;
}
I use Aron Kerrs CollectionInputFilter.
The storeName should be unique in the whole collection.
All works fine, so far!
But now my problem!
The streetName should be unique in the whole collection.
But the Element is in the AddressFieldset.
I can´t do something like this:
$storeInputFilter->setUniqueFields(array('storeName', 'address' => array('streetName')));
I thought I should extend Aron Kerrs isValid() from CollectionInputFilter
Aron Kerrs Original isValid()
public function isValid()
{
$valid = parent::isValid();
// Check that any fields set to unique are unique
if($this->uniqueFields)
{
// for each of the unique fields specified spin through the collection rows and grab the values of the elements specified as unique.
foreach($this->uniqueFields as $k => $elementName)
{
$validationValues = array();
foreach($this->collectionValues as $rowKey => $rowValue)
{
// Check if the row has a deleted element and if it is set to 1. If it is don't validate this row.
if(array_key_exists('deleted', $rowValue) && $rowValue['deleted'] == 1) continue;
$validationValues[] = $rowValue[$elementName];
}
// Get only the unique values and then check if the count of unique values differs from the total count
$uniqueValues = array_unique($validationValues);
if(count($uniqueValues) < count($validationValues))
{
// The counts didn't match so now grab the row keys where the duplicate values were and set the element message to the element on that row
$duplicates = array_keys(array_diff_key($validationValues, $uniqueValues));
$valid = false;
$message = ($this->getMessage()) ? $this->getMessage() : $this::UNIQUE_MESSAGE;
foreach($duplicates as $duplicate)
{
$this->invalidInputs[$duplicate][$elementName] = array('unique' => $message);
}
}
}
return $valid;
}
}
First of all I try (just for testing) to add a error message to streetName in the first entry of the collection.
$this->invalidInputs[0]['address']['streetName'] = array('unique' => $message);
But it doens´t work.
Adding it to storeName it works
$this->invalidInputs[0]['storeName'] = array('unique' => $message);
I think the reason is the Fieldset has an own InputFilter()?
When i do a var_dump($this->collectionValues()) i received a multidimensional array of all values (also of the addressFieldset).
That´s fine! But i can´t add error messages to the element in the fieldset.
How can i do this?
I don´t want to insert all Elements of the AddressFieldset in the StoreEntityFieldset. (I use the AddressFieldset also in other Forms)
I figured it out. You simply can add values with
$this->invalidInputs[<entry-key>]['address']['streetName'] = array('unique' => $message);
I don´t know how it does not work yesterday. It was another bug.
I wrote a solution for my problem. Maybe it´s not the best, but it works for me.
CollectionInputFilter
class CollectionInputFilter extends ZendCollectionInputFilter
{
protected $uniqueFields;
protected $validationValues = array();
protected $message = array();
const UNIQUE_MESSAGE = 'Each item must be unique within the collection';
/**
* #return the $message
*/
public function getMessageByElement($elementName, $fieldset = null)
{
if($fieldset != null){
return $this->message[$fieldset][$elementName];
}
return $this->message[$elementName];
}
/**
* #param field_type $message
*/
public function setMessage($message)
{
$this->message = $message;
}
/**
* #return the $uniqueFields
*/
public function getUniqueFields()
{
return $this->uniqueFields;
}
/**
* #param multitype:string $uniqueFields
*/
public function setUniqueFields($uniqueFields)
{
$this->uniqueFields = $uniqueFields;
}
public function isValid()
{
$valid = parent::isValid();
// Check that any fields set to unique are unique
if($this->uniqueFields)
{
foreach($this->uniqueFields as $key => $elementOrFieldset){
// if the $elementOrFieldset is a fieldset, $key is our fieldset name, $elementOrFieldset is our collection of elements we have to check
if(is_array($elementOrFieldset) && !is_numeric($key)){
// We need to validate every element in the fieldset that should be unique
foreach($elementOrFieldset as $elementKey => $elementName){
// $key is our fieldset key, $elementName is the name of our element that should be unique
$validationValues = $this->getValidCollectionValues($elementName, $key);
// get just unique values
$uniqueValues = array_unique($validationValues);
//If we have a difference, not all are unique
if(count($uniqueValues) < count($validationValues))
{
// The counts didn't match so now grab the row keys where the duplicate values were and set the element message to the element on that row
$duplicates = array_keys(array_diff_key($validationValues, $uniqueValues));
$valid = false;
$message = ($this->getMessageByElement($elementName, $key)) ? $this->getMessageByElement($elementName, $key) : $this::UNIQUE_MESSAGE;
// set error messages
foreach($duplicates as $duplicate)
{
//$duplicate = our collection entry key, $key is our fieldsetname
$this->invalidInputs[$duplicate][$key][$elementName] = array('unique' => $message);
}
}
}
}
//its just a element in our collection, $elementOrFieldset is a simple element
else {
// in this case $key is our element key , we don´t need the second param because we haven´t a fieldset
$validationValues = $this->getValidCollectionValues($elementOrFieldset);
$uniqueValues = array_unique($validationValues);
if(count($uniqueValues) < count($validationValues))
{
// The counts didn't match so now grab the row keys where the duplicate values were and set the element message to the element on that row
$duplicates = array_keys(array_diff_key($validationValues, $uniqueValues));
$valid = false;
$message = ($this->getMessageByElement($elementOrFieldset)) ? $this->getMessageByElement($elementOrFieldset) : $this::UNIQUE_MESSAGE;
foreach($duplicates as $duplicate)
{
$this->invalidInputs[$duplicate][$elementOrFieldset] = array('unique' => $message);
}
}
}
}
}
return $valid;
}
/**
*
* #param type $elementName
* #param type $fieldset
* #return type
*/
public function getValidCollectionValues($elementName, $fieldset = null){
$validationValues = array();
foreach($this->collectionValues as $rowKey => $collection){
// If our values are in a fieldset
if($fieldset != null && is_array($collection[$fieldset])){
$rowValue = $collection[$fieldset][$elementName];
}
else{
//collection is one element like $key => $value
$rowValue = $collection[$elementName];
}
// Check if the row has a deleted element and if it is set to 1. If it is don't validate this row.
if($rowValue == 1 && $rowKey == 'deleted') continue;
$validationValues[$rowKey] = $rowValue;
}
return $validationValues;
}
public function getMessages()
{
$messages = array();
if (is_array($this->getInvalidInput()) || $this->getInvalidInput() instanceof Traversable) {
foreach ($this->getInvalidInput() as $key => $inputs) {
foreach ($inputs as $name => $input) {
if(!is_string($input) && !is_array($input))
{
$messages[$key][$name] = $input->getMessages();
continue;
}
$messages[$key][$name] = $input;
}
}
}
return $messages;
}
}
Define a CollectionInputFilter (in a factory)
$storeInputFilter = new CollectionInputFilter();
$storeInputFilter->setInputFilter(new StoreEntityFieldsetInputFilter());
$storeInputFilter->setUniqueFields(array('storeName', 'address' => array('streetName')));
$storeInputFilter->setMessage(array('storeName' => 'Just insert one entry with this store name.', 'address' => array('streetName' => 'You already insert a store with this street name')));
$formFilter->get('company')->add($storeInputFilter, 'stores');
So let me explain:
Now, we can add elements as unique in fieldsets in our collection.
We can NOT add collection fieldsets in our collection and not another fieldsets in our fieldsets.
In my opinion if anyone want to do this cases, they better should refactor the form :-)
setUniqueFields
Add a simple element as unique
array('your-unique-element','another-element');
If you want to add a element as unique in a fieldset
array('your-unique-element', 'fieldsetname' => array('your-unique-element-in-fieldset'))
We can add special messages for every element with setMessage
Add Message for a Element in the collection
array('storeName' => 'Just insert one entry...')
Add message for a Element in a fieldset
array('fieldset-name' => array('your-unique-element-in-fieldset' => 'You already insert ..'))
I'm currently working on a project using the Phalcon Framework that has pages with complex forms and a lot of inputs, to break it down nicely I'm dividing the forms into a step-by-step process.
How would one validate the form on each step before going to the next step and then save the whole form on the final step?
I can't seem to find anything documented about this sort of process as it likes to validate the form in it's entirety if I use the form builder.
Simple, just create a custom methods in your form class to validate any step, and the posted data from some step save into message class and store it into session by "stepX", when posted data is not valid just set defaults from post. When valid save it into session as i describe above.
For example how i mean "controller"
<?php
class MyController extends BaseController {
public function processStep1Action(){
$form = new MyForm();
if($this->request->isPost()){//im using my custom request class
if(!$form->isValid($this->request->getPost()){
//error messages goes here
$form->setDefaultsFromRequest($this->request); // it will set the filled data
}
else {
$messageClass = new MyMessageContainer();
$messageClass->setData($this->request);//inside parse requested data into message class, or parse it as $messageClass->name = $this->request->getPost('name');
$this->session->save('step1',$messageClass); //maybe it would be want to serialize it
//then redirect to the step 2 or x
}
}
}
}
So in the next step you can access data from sessions $this->session->get('step1'); so you can in final step load all posted data and store it into DB.
I hope this helps! :)
here is my form maybe it can be helpful for you.
<?php
namespace Manager\Library\Forms\User;
use Phalcon\Forms\Form,
Phalcon\Forms\Element\Email,
Phalcon\Forms\Element\Select,
Phalcon\Forms\Element\Password,
Phalcon\Forms\Element\Check,
Phalcon\Validation\Validator\Confirmation,
Phalcon\Validation\Validator\StringLength,
Phalcon\Forms\Element\Submit,
Phalcon\Validation\Validator\PresenceOf,
Model\Group;
class AddUser extends Form {
public function initialize()
{
$email = new Email('email');
$email->addValidators(array(
new \Phalcon\Validation\Validator\Email(array(
'message' => 'Nezadali jste email nebo má nesprávny tvar(email#domena.tld).'
))
));
$this->add($email);
$this->initGroupElement();
$password = new Password('password');
$password
->addValidator(new StringLength(array('min' => 6,'messageMinimum' => 'Nezadali jste heslo nebo je příliš krátke, minimální počet znaků je 6.')))
->addValidator(new Confirmation(array('with' => 'password-again',"message" => "Zadané hesla se neshodují.")));
$this->add($password);
$repeatPassword = new Password('password-again');
$this->add($repeatPassword);
$this->initializeProfileElements();
$active = new Check('active',array('value' => 1));
$this->add($active);
$this->add( new Submit('save') );
\Phalcon\Tag::setDefault('password', '');
\Phalcon\Tag::setDefault('password-again', '');
}
public function initializeEdit(){
$email = new Email('email');
$email->addValidators(array(
new \Phalcon\Validation\Validator\Email(array(
'message' => 'Nezadali jste email nebo má nesprávny tvar(email#domena.tld).'
))
));
$this->add($email);
$this->initGroupElement();
$password = new Password('password');
$this->add($password);
$repeatPassword = new Password('password-again');
$this->add($repeatPassword);
$this->initializeProfileElements();
$active = new Check('active',array('value' => 1));
$this->add($active);
$this->add( new Submit('save') );
\Phalcon\Tag::setDefault('password', '');
\Phalcon\Tag::setDefault('password-again', '');
}
protected function initGroupElement(){
$auth = \Core\Auth::getIdentity();
$groups = new Group();
// $groups->addColumns(array('id','name'));
//set global condition about Super Admin
$groups->addFilter('id', 1,'<>');
if($auth){
//set restrictions for main groups
if((int)$auth->group_id === 1){ //super admingroup
//no filter
}
else if((int)$auth->group_id === 2){ //admin group
$groups->addFilter('id', 1,'>');
}
else if((int)$auth->group_id === 6){//Provozovatel group
$groups->addFilter('id',array(3,6,7));
$groups->addFilter('public', 1,'=',true);
}
else { // other groups
$groups->addFilter('public', 1);
}
}
$groups = $groups->findFiltered();
$groupElement = new Select('group');
foreach($groups as $group){
$groupElement->addOption(array($group->id => $group->name));
}
$this->add($groupElement);
}
protected function initializeProfileElements(){
$forename = new \Phalcon\Forms\Element\Text('forename');
$this->add($forename);
$surname = new \Phalcon\Forms\Element\Text('surname');
$this->add($surname);
$street = new \Phalcon\Forms\Element\Text('street');
$this->add($street);
$postal = new \Phalcon\Forms\Element\Text('postal');
$this->add($postal);
$city = new \Phalcon\Forms\Element\Text('city');
$this->add($city);
$ic = new \Phalcon\Forms\Element\Text('ic');
$this->add($ic);
$dic = new \Phalcon\Forms\Element\Text('dic');
$this->add($dic);
}
public function setDefault($fieldName,$value){
\Phalcon\Tag::setDefault($fieldName, $value);
}
public function setDefaults($object){
if($object instanceof \Model\User){
$this->setDefaultsFromObject($object);
}
else if($object instanceof \Phalcon\Http\Request){
$this->setDefaultsFromRequest($object);
}
}
protected function setDefaultsFromObject(\Model\User $user){
$profile = $user->getRelated('\Model\Profile');
\Phalcon\Tag::setDefaults(array(
'email' => $user->email,
'group' => $user->group_id,
'active' => $user->active,
'forename' => $profile->forename,
'surname' => $profile->surname,
'street' => $profile->street,
'city' => $profile->city,
'postal' => $profile->postal,
'ic' => $profile->IC,
'dic' => $profile->DIC
));
}
protected function setDefaultsFromRequest(\Phalcon\Http\Request $request){
\Phalcon\Tag::setDefaults(array(
'email' => $request->getPost('email'),
'group' => $request->getPost('group'),
'active' => $request->getPost('active')
));
\Phalcon\Tag::setDefaults(array(
'forename' => $request->getPost('forename'),
'surname' => $request->getPost('surname'),
'street' => $request->getPost('street'),
'city' => $request->getPost('city'),
'postal' => $request->getPost('postal'),
'ic' => $request->getPost('ic'),
'dic' => $request->getPost('dic')
));
}
}
In addition to Kamil's answer, another option to consider is to use Javascript on the front-end to handle your multi-step form. This will add some complexity as you will need to have the javascript to handle the form steps and do preliminary validation, but it only requires a single submit where you can validate content within a single method.
i make a setting action in which i used doctrine query for getting single result but it returns null while data exist in database,how i get single result?here is my code:
public function settingsAction()
{
$id = (int) $this->params()->fromRoute('id', 0);
if (!$id) {
return $this->redirect()->toRoute('calendar', array(
'action' => 'create'
));
}
//echo $id;
//$calendar = $id;//$this->getCalendarTable()->getCalendar($id);
$calendar = $documentManager->getRepository('Calendar\Document\Calendar')->find($id);
$form = new CalendarForm();
$form->bind($calendar);
$form->get('submit')->setAttribute('value', 'Save');
$request = $this->getRequest();
if ($request->isPost()) {
$form->setInputFilter($calendar->getInputFilter());
$form->setData($request->getPost());
if ($form->isValid()) {
//$this->getCalendarTable()->saveCalendar($form->getData());
return $this->redirect()->toRoute('calendar', array('action' => 'show', 'id' => $id));
}
}
return array(
'id' => $id,
'form' => $form,
);
}
You don't need to create a query to fetch by id as the DocumentRepository already provides this via it's find($id) method.
Just use the document manager to fetch the repository
$document = $documentManager->getRepository('FooDocument')->find($id);
You can also use the convenience method find($documentName, $id) directly on the document manager.
$document = $documentManager->find('FooDocument', $id);
I have file (ProfileController.php) which contains the following code:
public function editAction() {
if (Zend_Auth::getInstance()->hasIdentity()) {
try {
$form = new Application_Form_NewStory();
$request = $this->getRequest();
$story = new Application_Model_DbTable_Story();
$result = $story->find($request->getParam('id'));
// $values = array(
// 'names' => $result->names,
// 'password' => $result->password,
// );
if ($this->getRequest()->isPost()) {
if ($form->isValid($request->getPost())) {
$data = array(
'names' => $form->getValue("names"),
'password' => $form->getValue("password"),
);
$form->populate($data->toArray());
$where = array(
'id' => $request->getParam('id'),
);
$story->update($data, $where);
}
}
$this->view->form = $form;
$this->view->titleS= $result->title;
$this->view->storyS= $result->story;
} catch (Exception $e) {
echo $e;
}
} else {
$this->_helper->redirector->goToRoute(array(
'controller' => 'auth',
'action' => 'index'
));
}
}
and another file (edit.phtml) with following code:
<?php
try
{
$tmp = $this->form->setAction($this->url());
//$tmp->titleS=$this->title;
//$tmp->storyS=$this->story;
//echo $tmp->title = "aaaaa";
}
catch(Exception $e)
{
echo $e;
}
?>
I would like the users to be able to edit their Username and password. How do I go about it?
First: move the Zend_Auth stuff up to init() or preDispatch(), that way Auth will run against any or all actions in the controller.
The trick in getting more then one submit button to work is to give the buttons different names so that getParam('') has something to work with.
Normally I only do this sort of thing when doing deletes, for edit's or update's I just submit the whole array back to the database. I typically use the Zend_Db_Table_Row save() method instead of Zend_Db_Table's insert() or update() so the mechanism is a little different.
I just use a simple form to perform an update, here is the controller code (the view just echo's the form):
//update album information
public function updatealbumAction()
{ //get page number from session
$session = new Zend_Session_Namespace('page');
//get album id
$id = $this->getRequest()->getParam('id');
$model = new Music_Model_Mapper_Album();
//fetch the album database record
$album = $model->findById($id);
$form = new Admin_Form_Album();
//this form is used elsewhere so set the form action to this action
$form->setAction('/admin/music/updatealbum/');
if ($this->getRequest()->isPost()) {
if ($form->isValid($this->getRequest()->getPost())) {
$data = $form->getValues();//get valid and filtered form values
$newAlbum = new Music_Model_Album($data);//create new entity object
$update = $model->saveAlbum($newAlbum);//save/update album info
$this->message->addMessage("Update of Album '$update->name' complete!");//generate flash message
$this->getHelper('Redirector')->gotoSimple('update', null, null, array('page' => $session->page));//redirect back to the page the request came from
}
} else {
$form->populate($album->toArray());
$this->view->form = $form;
}
}
This is a pretty common update action.
Now here is how you might use different request parameters to perform an action on a record. I use this to delete database records but anything is possible.
public function deleteAction()
{
$session = new Zend_Session_Namespace('page');
$request = $this->getRequest()->getParams();
try {
switch ($request) {
//if
case isset($request['trackId']):
$id = $request['trackId'];
$model = new Music_Model_Mapper_Track();
$model->deleteTrack($id);
$this->message->addMessage("Track Deleted!");
break;
case isset($request['albumId']):
$id = $request['albumId'];
$model = new Music_Model_Mapper_Album();
$model->deletealbum($id);
$this->message->addMessage("Album Deleted!");
break;
case isset($request['artistId']):
$id = $request['artistId'];
$model = new Music_Model_Mapper_Artist();
$model->deleteArtist($id);
$this->message->addMessage("Artist Deleted!");
break;
default:
break;
}
$this->getHelper('Redirector')->gotoSimple('update', null, null, array('page' => $session->page));
} catch (Exception $e) {
$this->message->addMessage($e->getMessage());
$this->getHelper('Redirector')->gotoSimple('update', null, null, array('page' => $session->page));
}
}
you can pass the request parameters as submit button labels or as urls or whatever works for you.
Good Luck!
I'm really new to silex and symfony. This is my first foray into silex. I've got code that created my form in my app.php file from a little hacking and copying and pasting from documentation.
Now how do i pass this data to another page?
I would like to create a page that just dumps the post/get array to give me an idea how to pass around get/post variables.
Here's part of my app file:
<?php
/** /src/app.php */
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
/**
* Register new application
*/
$app = new Application();
// skip to the form part ...
$app->match('/', function (Request $request) use ($app) {
// some default data for when the form is displayed the first time
$data = array(
'name' => 'Your name',
'email' => 'Your email',
);
$form = $app['form.factory']->createBuilder('form', $data)
->add('name')
->add('email')
->add('gender', 'choice', array(
'choices' => array(1 => 'male', 2 => 'female'),
'expanded' => true,
))
->getForm();
if ('POST' == $request->getMethod()) {
$form->bindRequest($request);
if ($form->isValid()) {
$data = $form->getData();
// do something with the data
// redirect somewhere
return $app->redirect('completed');
}
}
// display the form
return $app['twig']->render('index.html', array('form' => $form->createView()));
});
Would i then create a page like so?
<?php // app.php
$app->match('complete') use function ($app) {
// sorry psuedocode
foreach ($REQUEST as $key=> $var) {
echo "$key: $var";
}
}
You could try using a forward. http://silex.sensiolabs.org/doc/usage.html#fowards
// where params is the values from your POST
$subRequest = Request::create('/otherpage', 'GET', $params);
return $app->handle($subRequest, HttpKernelInterface::SUB_REQUEST);