how to change url management flow in yii - php

i have implementing the project in yii. i done my project but i want to change instead of id to name. ie url management. i did uncomment in config.php then i added the following code. those follows:
my table name is recipe:
public function loadModel($id)
{
$model=Recipe::model()->findByPk($id);
if($model===null)
throw new CHttpException(404,'The requested page does not exist.');
return $model;
}
public function loadModel2($name)
{
$model=Recipe::model()->find('t.name=:name', array(':name' => $name));
if($model===null)
throw new CHttpException(404,'The requested page does not exist.');
return $model;
}
except this i added top of the sitecontroller use Recipe. but it shows error is
The use statement with non-compound name 'Recipe' has no effect
please suggest me suitable answer

I personally use in my projects something like /product-name/p/1 and this is SEO friendly. To get your links to look like that you have to first change your url rules
'urlManager' => array(
'urlFormat' => 'path',
'showScriptName' => false,
'urlSuffix' => '/',
'rules' => array(
'<title:.*?>/p/<id:\d+>'=>'product/view',
),
),
Then use this to create your URLs.
Yii::app()->createUrl('product/view',array('id'=>$model->id, 'title'=>$model->name))
Now it works both ways, the create url will always create urls like /product-name/p/1 and further more you can show the product the normal way
/**
* Displays a particular model.
* #param integer $id the ID of the model to be displayed
*/
public function actionView($id)
{
$model = $this->loadModel($id);
$this->render('view',array(
'model'=>$model,
));
}

Related

PrestaShop 1.7 Add new resources and class

I created new resources with this code:
class WebserviceRequest extends WebserviceRequestCore {
public static function getResources(){
$resources = parent::getResources();
// if you do not have class for your table
$resources['test'] = array('description' => 'Manage My API', 'specific_management' => true);
$resources['categoryecommerce'] = array('description' => 'o jacie marcin', 'class' => 'CategoryEcommerce');
$mp_resource = Hook::exec('addMobikulResources', array('resources' => $resources), null, true, false);
if (is_array($mp_resource) && count($mp_resource)) {
foreach ($mp_resource as $new_resources) {
if (is_array($new_resources) && count($new_resources)) {
$resources = array_merge($resources, $new_resources);
}
}
}
ksort($resources);
return $resources;
}
}
And new class:
class CategoryEcommerceCore extends ObjectModelCore {
public $category_id;
public $category_core_id;
public static $definition = array(
'table' => "category_ecommerce",
'primary' => 'category_id',
'fields' => array(
'category_core_id' => array('type' => self::TYPE_INT),
)
);
protected $webserviceParameters = array();
}
Webservice is override properly. My class WebserviceRequest is copying to
/override/classes/webservice/WebserviceRequest
but class isn't copying to /override/classes/ when i installing my module.
How to add new resourcess with own logic ? I want to add categories within relation to my table.
Regards
Martin
As soon as there is literally nothing regarding the API except Webkul tutorial... I tried to implement the "Webkul's" tutorial, but also failed. However seems that it's better to use hooks instead of overrides. I used my "reverse engineering skills" to determine the way to create that API, so-o-o-o, BEHOLD! :D
Let's assume you have a custom PrestaShop 1.7 module. Your file is mymodule.php and here are several steps.
This is an install method wich allows you to register the hook within database (you can uninstall and reinstall the module for this method to be executed):
public function install() {
parent::install();
$this->registerHook('addWebserviceResources');
return true;
}
Add the hook listener:
public function hookAddWebserviceResources($resources) {
$added_resources['test'] = [
'description' => 'Test',
'specific_management' => true,
];
return $added_resources;
}
That specific_management option shows you are going to use WebsiteSpecificManagement file instead of database model file.
Create WebsiteSpecificManagement file, called WebsiteSpecificManagementTest (Test - is CamelCased name of your endpoint). You can take the skeleton for this file from /classes/webservice/WebserviceSpecificManagementSearch.php. Remove everything except:
setObjectOutput
setWsObject
getWsObject
getObjectOutput
setUrlSegment
getUrlSegment
getContent (should return $this->output; and nothing more)
manage - you should rewrite it to return/process the data you want.
Add
include_once(_PS_MODULE_DIR_.'YOURMODULENAME/classes/WebserviceSpecificManagementTest.php');
to your module file (haven't figured out how to include automatically).
Go to /Backoffice/index.php?controller=AdminWebservice and setup the new "Auth" key for your application, selecting the test endpoint from the permissions list. Remember the key.
Visit /api/test?ws_key=YOUR_KEY_GENERATED_ON_STEP_4 and see the XML response.
Add &output_format=JSON to your URL to see the response in JSON.
You have to use something like $this->output = json_encode(['blah' => 'world']) within manage method at WebsiteSpecificManagementTest.

FileNameController cannot find the requested view "create" in Yii 1

I have upload a new form in an existing webapp which is live (Linux server). But I am not able to set the route properly and get error.
Files :
1. view/newform/(create,index,view,_view,_form).php
controllers/NewFormController.php
models/NewForm.php
main.php :
'urlManager' => array(
'showScriptName' => false,
'urlFormat' => 'path',
'rules' => array(
'/' => 'site/index',
'newform' => 'newform/create', /*This rule is for new form */
**********************************
Link I use to access the wbepage online :
websitename.com/newform/create or create.php (I get 404 not found)
websitename.com/NewForm/create or create.php (NewFormController cannot find the requested view "create" error )
I can view it properly on localhost(windows) =>
localhost/public_html/index.php?r=newform/create
Questions :
What link should I use to view it online ?
How to get correct Route to the form I created ?
Edited :
I can view the index page after adding the path (/newform/index) in actionIndex(). controller
public function actionIndex()
{
$dataProvider=new CActiveDataProvider('NewForm');
$this->render('/newform/index',array(
'dataProvider'=>$dataProvider,
));
}
Here is the create function :
When I use this the error I get : cannot find the requested view "_form"
public function actionCreate()
{
$model=new NewForm;
// Uncomment the following line if AJAX validation is needed
// $this->performAjaxValidation($model);
if(isset($_POST['NewForm']))
{
$model->attributes=$_POST['NewForm'];
if($model->save())
$this->redirect(array('view','id'=>$model->id));
}
$this->render('/newform/create',array(
'model'=>$model,
));
}
Found It :P
$this->render('/newform/_form',array(
'model'=>$model,
));
in crontroller

active status is disabled when creating individual zend navigaton pages

I have the following code:
class Module {
public function onBootstrap(MvcEvent $e){
$application = $e->getApplication();
$em = $application->getEventManager();
$em->attach(\Zend\Mvc\MvcEvent::EVENT_DISPATCH, array($this,'setupNav'),10000);
}
public function setupNav($e)
{
$serviceLocator = $e->getApplication()->getServiceManager();
$router = $serviceLocator->get('router');
$page = \Zend\Navigation\Page\AbstractPage::factory(array(
'label' => 'Login',
'route' => 'login',
'resource' => 'auth.auth.login'
));
$page->setRouter($router);
$page->set('type','user');
$serviceLocator->get('navigation')->addPage($page);
}
}
The problem is that these pages i create dynamically dont ever get marked as status active when the route matches (and adds an active class). It works fine for the ones loaded with the navigation container (the config navigation) but for some reason when i dynamically add Mvc Pages the status does not become active for these navigation elements

Zend Framework 2: Navigation

In my controller I create the Navigation object and passing it to the view
$navigation = new \Zend\Navigation\Navigation(array(
array(
'label' => 'Album',
'controller' => 'album',
'action' => 'index',
'route' => 'album',
),
));
There trying to use it
<?php echo $this->navigation($this->navigation)->menu() ?>
And get the error:
Fatal error: Zend\Navigation\Exception\DomainException: Zend\Navigation\Page\Mvc::getHref cannot execute as no Zend\Mvc\Router\RouteStackInterface instance is composed in Zend\View\Helper\Navigation\AbstractHelper.php on line 471
But navigation which I use in layout, so as it is written here: http://adam.lundrigan.ca/2012/07/quick-and-dirty-zf2-zend-navigation/ works. What is my mistake?
Thank you.
The problem is a missing Router (or to be more precise, a Zend\Mvc\Router\RouteStackInterface). A route stack is a collection of routes and can use a route name to turn that into an url. Basically it accepts a route name and creates an url for you:
$url = $routeStack->assemble('my/route');
This happens inside the MVC Pages of Zend\Navigation too. The page has a route parameter and when there is a router available, the page assembles it's own url (or in Zend\Navigation terms, an href). If you do not provide the router, it cannot assemble the route and thus throws an exception.
You must inject the router in every page of the navigation:
$navigation = new Navigation($config);
$router = $serviceLocator->get('router');
function injectRouter($navigation, $router) {
foreach ($navigation->getPages() as $page) {
if ($page instanceof MvcPage) {
$page->setRouter($router);
}
if ($page->hasPages()) {
injectRouter($page, $router);
}
}
}
As you see it is a recursive function, injecting the router into every page. Tedious! Therefore there is a factory to do this for you. There are four simple steps to make this happen.
STEP ONE
Put the navigation configuration in your module configuration first. Just as you have a default navigation, you can create a second one secondary.
'navigation' => array(
'secondary' => array(
'page-1' => array(
'label' => 'First page',
'route' => 'route-1'
),
'page-2' => array(
'label' => 'Second page',
'route' => 'route-2'
),
),
),
You have routes to your first page (route-1) and second page (route-2).
STEP TWO
A factory will convert this into a navigation object structure, you need to create a class for that first. Create a file SecondaryNavigationFactory.php in your MyModule/Navigation/Service directory.
namespace MyModule\Navigation\Service;
use Zend\Navigation\Service\DefaultNavigationFactory;
class SecondaryNavigationFactory extends DefaultNavigationFactory
{
protected function getName()
{
return 'secondary';
}
}
See I put the name secondary here, which is the same as your navigation key.
STEP THREE
You must register this factory to the service manager. Then the factory can do it's work and turn the configuration file into a Zend\Navigation object. You can do this in your module.config.php:
'service_manager' => array(
'factories' => array(
'secondary_navigation' => 'MyModule\Navigation\Service\SecondaryNavigationFactory'
),
)
See I made a service secondary_navigation here, where the factory will return a Zend\Navigation instance then. If you do now $sm->get('secondary_navigation') you will see that is a Zend\Navigation\Navigation object.
STEP FOUR
Tell the view helper to use this navigation and not the default one. The navigation view helper accepts a "navigation" parameter where you can state which navigation you want. In this case, the service manager has a service secondary_navigation and that is the one we need.
<?= $this->navigation('secondary_navigation')->menu() ?>
Now you will have the navigation secondary used in this view helper.
Disclosure: this answer is the same as I gave on this question: https://stackoverflow.com/a/12973806/434223
btw. you don't need to define controller and action if you define a route, only if your route is generic and controller/action are variable segments.
The problem is indeed that the routes can't be resolved without the router. I would expect the navigation class to solve that issue, but obviously you have to do it on your own. I just wrote a view helper to introduce the router with the MVC pages.
Here's how I use it within the view:
$navigation = $this->navigation();
$navigation->addPage(
array(
'route' => 'language',
'label' => 'language.list.nav'
)
);
$this->registerNavigationRouter($navigation);
echo $navigation->menu()->render();
The view helper:
<?php
namespace JarJar\View\Helper;
use Zend\View\Helper\AbstractHelper;
use Zend\View\Helper\Navigation;
use Zend\ServiceManager\ServiceLocatorAwareInterface;
use Zend\ServiceManager\ServiceLocatorInterface;
use Zend\Navigation\Page\Mvc;
class RegisterNavigationRouter extends AbstractHelper implements ServiceLocatorAwareInterface
{
protected $serviceLocator;
public function setServiceLocator(ServiceLocatorInterface $serviceLocator)
{
$this->serviceLocator = $serviceLocator;
}
public function getServiceLocator()
{
return $this->serviceLocator;
}
public function __invoke(Navigation $navigation)
{
$router = $this->getRouter();
foreach ($navigation->getPages() as $page) {
if ($page instanceof Mvc) {
$page->setRouter($router);
}
}
}
protected function getRouter()
{
$router = $this->getServiceLocator()->getServiceLocator()->get('router');
return $router;
}
}
Don't forget to add the view helper in your config as invokable instance:
'view_helpers' => array(
'invokables' => array(
'registerNavigationRouter' => 'JarJar\View\Helper\RegisterNavigationRouter'
)
),
It's not a great solution, but it works.

Zend: Issues setting up editAction(), please advise

I am experiencing some difficulty setting up the functionality for an admin to edit an items values. I have created the editAction() function in the AdminItemController class. This is contained within a module called catalog. My routing is configured as the following:
resources.router.routes.admin-catalog-edit.route = "/admin/catalog/item/edit/:id"
resources.router.routes.admin-catalog-edit.defaults.module = "catalog"
resources.router.routes.admin-catalog-edit.defaults.controller = "admin.item"
resources.router.routes.admin-catalog-edit.defaults.action = "edit"
I have created a custom Zend_Form class and within this class I set the action and method for the form:
class My_Form_ItemAdd extends Zend_Form
{
public function init()
{
$this->setAction('/admin/catalog/item/edit')
->setMethod('post');
...
Within my controller action I have instantiated the form and pass it to the view to be rendered. I also test if it's a POST (if so validate and save to database), otherwise, test for GET (if so, extract ID and populate()):
class Catalog_AdminItemController extends Zend_Controller_Action
{
...
public function editAction()
{
$form = new My_Form_ItemEdit();
$this->view->form = $form;
...
The form loads just fine in the browser when I supply an ID at the end for GET request... however, when I submit the form an exception is thrown with the following request parameters:
array (
'controller' => 'admin',
'action' => 'catalog',
'item' => 'edit',
'module' => 'default',
...
I have no idea why the it would be doing this... is there something I'm not seeing??? Any advice would be much appreciated!
The problem lies in your route. The default behavior for /admin/catalog/item/edit/:id is to process it like /controller/action/:param/:param/:param which puts both item and edit as parameters instead of your intended purpose. Try adding something like this to your bootstrap:
protected function _initRoutes()
{
// Get front controller
$front = Zend_Controller_Front::getInstance();
// Get router
$router = $front->getRouter();
// Add route
$router->addRoute(
'admin_item_edit',
new Zend_Controller_Router_Route('admin/catalog/item/edit/:id',
array('controller' => 'item',
'action' => 'edit'))
);
}
This allows you to define the specific controller and action from the route.

Categories