Sitemap for dynamic website - codeigniter - codeigniter-3

I have a dynamic website designed with Codeigniter 3 and I am working on the sitemap part as a newbie.
I found the library sitemap-php from evert/sitemap-php but I can't make it run.
From now this is what I did, I put the Sitemap.php file into my library folder
Controller:
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
class Deals extends CI_Controller {
public function __construct(){
parent::__construct();
$this->load->helper('url', 'form', 'security');
$this->load->library('form_validation');
$this->load->library('session');
$this->load->library('email');
$this->load->model('deal_model');
$this->load->helper(array('cookie','custom','text'));
}
public function Sitemap(){
$this->load->library('Sitemap');
$sitemap = new Sitemap('https://www.mywebsite.com');
$sitemap->setPath('/public_html/Sitemap/'); // I created a folder Sitemap into my public folder
$sitemap->setFilename('sitemap');
$sitemap->addItem('/', '1.0', 'daily', 'Today');
$sitemap->createSitemapIndex('https://www.mywebsite.com/sitemap/', 'Today');
}
Then when I go to https://www.mywebsite.com/sitemap/, I have an Error 404.
Could you guide me to solve my issue.
Thanks

The docs for that library describe that it generates a static XML file. The code you've shown will do that - but your code is in a Library, and you have not run it yet. You need to run it, then it will generate an XML file as you've specified, in /public_html/Sitemap/. From your description you are looking for the XML before doing anything to generate it, and it does not (yet) exist.
From your updated code, you now have the code to generate the static XML available as a Controller method. According to the standard Codeigniter routing conventions, the method you have created is accessible at:
http://your-site/deals/Sitemap
(Maybe you've also set up some routes so it is accessible at other URIs also.)
Visit that URL, once, to generate the static XML file at /public_html/Sitemap/sitemap.xml. Assuming your code works, you should then be able to browse the XML at
http://your-site/Sitemap/sitemap.xml
Side note: AFAIK Codeigniter convention is for capitalised Controller file and class names (Deal.php and Deal), but all lower-case method names (sitemap() instead of Sitemap()). You can see examples of this in the Controller docs I linked above. I am not sure if it matters, just pointing it out.

Related

How can I add simple CMS functionality to existing Symfony application

I have an existing web application accessing a MySQL database. I'm porting this application to Symfony. The new application has to use the old database, as we cannot port the whole application at once, i.e. the old and the new application are accessing the same database and the applications are running simultaneously.
The old application had a simple CMS functionality which has to be ported:
There is a table pagewhich represents a page tree. Every page has a slug field. The URL path consists of those slugs representing the path identifying the page node, e.g. "/[parent-slug]/[child-slug]".
The page table also contains a content field. As I already mentioned, the CMS functionality is very simple, so the content is just rendered as page content inside a page layout. The page entry also specifies the page layout / template.
My problem is that I don't know how to set up the routing. In a normal Symfony application I'd know the URL patterns before, but in this case they are dynamic. Also routes cannot be cached, because they could be changed any time by the user. I wonder if I have to drop Symfony's routing completely and implement something on my own. But how?
Now I found Symfony CMF which tells a lot about the framework VS CMS routing conflict. So first, I thought this would be the right way. However the tutorials aim at building an entirely new application based on PHPRC. I wasn't able to derive the tutorial's concepts to my use case.
since you run several URL rules on one symfony application, you will need to work with url prefixes. Either your cms should work with a prefix /cms/parent-slug/child-slug or all other controllers. Otherwise you are not able to differ which controller is meant when a dynamic request arrives.
You can try a workaround with a KernelControllerListener. He will catch up every request and then check if a cms page is requested. On the basis of the request you can set controller and action by yourself. Concept:
Create only one route with "/". Abandon oll other rules. Then create a Listener like this:
<?php
namespace AppBundle\Listener;
use Symfony\Component\HttpKernel\Event\FilterControllerEvent;
/**
* Class KernelControllerListener
* #package ApiBundle\Listener
*/
class KernelControllerListener
{
/**
* #var CmsRepository
*/
private $requestParser;
/**
* KernelControllerListener constructor.
* #param CmsRepository $CmsRepository
*/
public function __construct(CmsRepository $CmsRepository)
{
$this->CmsRepository = $CmsRepository;
}
/**
* #param FilterControllerEvent $event
*/
public function onKernelController(FilterControllerEvent $event){
$request = $event->getRequest();
//should be /parent-slug/children/slug or any other path
$path = $request->getPathInfo();
if($this->CmsRepository->getCmsControllerIfMatch($path)){
//cms repository search in db for page with this path, otherwise return false
$event->setController([AppBundle\CmsController::class, 'cmsAction']);
return;
}
//repeat if clause for any other application part
}
}
in services.yml:
app.controller_listener:
class: AppBundle\Listener\KernelControllerListener
arguments:
- "#app.cms_repository"
tags:
- { name: kernel.event_listener, event: kernel.controller, method: onKernelController }
Edit: catch all routes, see https://www.jverdeyen.be/symfony2/symfony-catch-all-route/
The question is: Do you whant to migrate the data or not. For both question, the CMF can be an answer. If you wanna a simple dynamic router, you should have a look into the ChainRouter with an custom router definition:
https://symfony.com/doc/current/cmf/bundles/routing/dynamic.html
and
https://symfony.com/doc/current/cmf/components/routing/chain.html
If you wanna migrate the data, you can use fixture loaders, as we use in almost all of our examples.

Decode RealUrl url in the controller

I use RealUrl for my website. In my certain extension, I require to decode the url created by RealUrl to the normal TYPO3 url format.
Example:
To my controller I get this link : typo3website/feature/number/123 , now how do I convert this to typo3website/index.php?id=99&number=123
The RealUrl does not use namespace, and hence i'm unable to understand how to create an instance of the class tx_realurl.
I tried using require_once(PATH_typo3conf.'ext/realurl'.'/class.tx_realurl.php'); and creating new instance of tx_realurl, but gives a class not found error.
If RealURL is configured properly and the link is generated with the uriBuilder or the ActionViewHelper, you don't need to take care of that. If we take your example and you configured RealURL to use typo3website/feature/number/123 for index.php?id=99&tx_yourext[number]=123, you can use this as argument for your action:
public function showAction($number) {
}
You can also access all arguments from a controller action by using
$this->request->getArguments()

Zend_Form submission > Resource 'controller::action' not found

I'm taking over a site that's gone through several developers. The site is using Zend version 1.12.0, according to Zend_Version::VERSION, which is a new framework for me. On the site, there's a form class called App_Form_Customers_Edit, which extends Zend_Form. The form's action is /customers/edit, and when submitted, the method editAction of CustomersController is executed.
So, to create a new form, I created a new class App_Form_Customers_EditAddress in the same directory as App_Form_Customers_Edit, and set it's action to /customers/editaddress, created a function called editaddressAction in the CustomersController class and tested the form.
But I get an error saying "Resource 'customers::editaddress' not found"
The form itself is displaying properly, and as far as I can tell I'm using the exact same pattern as the other form which works, and apart from not using the zf command, the same method prescribed here in the Zend documentation: http://framework.zend.com/manual/1.12/en/learning.quickstart.create-form.html
What do I need to do to get my new form working? Do I need to update .zfproject.xml? I can't see anything in there that's related to the working form.
Here's the code for App_Form_Customers_Edit:
class App_Form_Customers_Edit extends Zend_Form
{
public function init ()
{
$this->addPrefixPath('App_Form', 'App/Form/');
$this->setMethod('post');
// ... The rest is just calls to $this->addElement
}
}
And for EditAddress:
class App_Form_Customers_EditAddress extends Zend_Form
{
public function init ()
{
$this->addPrefixPath('App_Form', 'App/Form/')
->setMethod('post')
->setAction('/customers/editaddress');
$this->addElement('submit', 'active', ['value' => 'Activate']);
$this->addElement('submit', 'remove', ['value' => 'Remove']);
$this->addElement('hidden', 'id');
}
}
Check for acl declarations. If you are using acl and you have not declared rules for the action, you might get this type of error.
Best guess:
Your former developer has implemented a custom route somewhere. Probably in the application.ini or the boostrap.php. This custom route is looking for specific urls and /customers/edit conforms to a valid route but /customers/editaddress does not.
I think this is likely because your error is a missing resource rather then a 'page not found' or a missing controller or missing action message. So it seems as though the router is trying to match an invalid resource to a valid route.
Good Luck

Zend Framework: get public path, get application url

Are there some proper Zend methods for:
a) receiving path to /public directory
b) receiving application url
Actually I'm using methods defined in Controller, but it feel right to use ready methods if they exits.
protected function _getApplicationUrl() {
return $_SERVER['SERVER_NAME'];
}
protected function _getPublicPath() {
return realpath(APPLICATION_PATH . '/../public/');
}
Regarding the application URL, Zend_Controller_Request_Http has a getRequestUri() method, but it deliberately (and somewhat frustratingly) excludes the scheme and hostname parts of the URL. In my apps I have resorted to grabbing $_SERVER['HTTP_HOST'] in the bootstrap and storing it in the registry so that I can use it later when constructing full URLs.
And from memory, no, there isn't any built-in method to get the location of the public folder, but the code you have is fine. Most apps I've seen define() all the paths in index.php, which I suppose is slightly safer (only because the path names get set sooner and become absolutely immutable) and ever so slightly faster, but lets not get into a debate about micro-optimizations! :-)
1) If your virtual host point to ZF /public then in View you can get path by helper method $this->baseUrl(); In controller $this->view->baseUrl(); Otherwise create your own helper and use it.
2) In controller $this->getRequest()->getHttpHost();
protected function _getPublicPath() {
chdir(APPLICATION_PATH);
return realpath("../public");
}
a) receiving path to /public directory
Built-in php-function getcwd() will give you the path to your site-host folder (ex. output "/home/my_cp/public_html/my_site.loc/www"). And then, you can construct whatever path you want.

Zend Framework website.com/username

One of the application I am developing using Zend Framework requires the user's profile page to be accessed via website.com/username, while other pages should be accessed by website.com/controller_name/action_name
I am not too sure how can this be achieved, however, I feel this can be done with some tweaks in the .htaccess file.
Can someone here please help me out?
Many thanks in advance
As suggested before, you can use a custom route that will route single level requests. However, this will also override the default route. If you're using modules, this will no longer work example.com/<module>.
I have done this before but only for static pages. I wanted this:
example.com/about
instead of this:
example.com/<some-id>/about
while maintaining the default route so this still works
example.com/<module>
example.com/<controller>
The way I did this was using a plugin to test if my request could be dispatched. If the request could not be dispatched using the default route, then I would change the request to the proper module to load my page. Here is a sample plugin:
class My_Controller_Plugin_UsernameRoute extends Zend_Controller_Plugin_Abstract
{
public function preDispatch(Zend_Controller_Request_Abstract $request)
{
$dispatcher = Zend_Controller_Front::getInstance()->getDispatcher();
if (!$dispatcher->isDispatchable($request)) {
$username = $request->getControllerName();
$request->setModuleName('users');
$request->setControllerName('dashboard');
$request->setActionName('index');
$request->setParam('username', $username);
/** Prevents infinite loop if you make a mistake in the new request **/
if ($dispatcher->isDispatchable($request)) {
$request->setDispatched(false);
}
}
}
}
What about using Zend_Controller_Router_Route, look here the link http://framework.zend.com/manual/en/zend.controller.router.html#zend.controller.router.routes.standard.variable-requirements