Joomla Component - SEF links on and JRequest::getVar not returning variables from encoded URL - joomla

I'm having trouble with my component and Joomla's SEF links. I'm trying to use JRequest::getVar to get the variables from the original URL (specified with JRoute::_)
My router.php file looks like this:
function PortfolioBuildRoute(&$query)
{
$segments = array();
if (isset($query['category'])) {
$segments[] = $query['category'];
unset($query['category']);
}
if (isset($query['subcategory'])) {
$segments[] = $query['subcategory'];
unset($query['subcategory']);
}
return $segments;
}
function PortfolioParseRoute($segments)
{
$vars = array();
$count = count($segments);
if ($count) {
$count--;
$segment = array_shift($segments);
if (is_numeric($segment)) {
$vars['subcategory'] = $segment;
} else {
$vars['category'] = $segment;
}
}
if ($count) {
$count--;
$segment = array_shift($segments) ;
if (is_numeric($segment)) {
$vars['subcategory'] = $segment;
}
}
return $vars;
}
The URL I'm encoding originally looks like:
index.php?option=com_portfolio&category=x&subcategory=y and JRoute::_ turns it into /portfolio/x/y. What I need now is some way of getting the variables x and y after the url is encoded?
----EDIT----
Ok so I figured it out - I changed the ParseRoute part of the router.php file to:
function PortfolioParseRoute($segments)
{
$vars = array();
$vars['category'] = str_replace(":", "-", $segments[0]);
$vars['subcategory'] = str_replace(":", "-", $segments[1]);
return $vars;
}
I feel I've got a slightly better understanding of the router.php file now. It turns out JRoute converts hyphens in your url to colons! Don't quite know why it picks on the poor hyphens, big JRoute bully. I could use underscores in the URL and it would function fine but hyphens are better SEO than underscores.
I used str_replace on each of the segments in ParseRoute to sort this out.
I'm not sure if this is the correct and standards way to go about this but I'm a Joomla and PHP noob so it will have to do until I'm advised otherwise.
At least it works!
:)

Related

Why does this pattern not work in preg_match

I use preg_match in a function to prevent image extensions from being submitted!
Now I want to block " ~ " character also!
Can anyone tell me how I can do that?
function is_valid($url) {
$res = 1;
if (isset($url['path'])) {
if (preg_match('/\b.jpg\b/i', $url['path'])) { $res = 0; }
if (preg_match('/\b.gif\b/i', $url['path'])) { $res = 0; }
if (preg_match('/\b.png\b/i', $url['path'])) { $res = 0; }
if (preg_match('/\b.bmp\b/i', $url['path'])) { $res = 0; }
}
return $res;
}
I tried this, but it does not work:
if (strpos('~', $url['path'])) {
$res = 0;
}
First of all, you should really read something about regular expressions! If you have done that, read the manual for phps strpos.
You may try preg_match('/[^~]+\.(png|jpg|gif|bmp)/i', $url['path']) or if you want to stick to your version,
if (strpos($url['path'], '~') !== FALSE) {
$res = 0;
}
But anyway, your check will just not be very safe. Example: Someone renames a php file into png and uploads it, if you have mime_magic activated on your apache, the code will get executed. So it is much safer to check the mimetype of the file. See How do I find the mime-type of a file with php? as an example. The accepted answer there mentions a (now) deprecated function, but you can use http://de3.php.net/manual/en/function.finfo-file.php if you have PHP 5.3+

Modify the existing canonical link in header

I am using Joomla 2.5 and I want to change the canonical link in the header.
I do this in category view (components/com_content/category/tmpl/default.php)
$url = JURI::root();
$sch = parse_url($url, PHP_URL_SCHEME);
$server = parse_url($url, PHP_URL_HOST);
$canonical = $this->escape($_SERVER['REQUEST_URI']);
$document->addCustomTag('<link rel="canonical" href="'.$sch.'://'.$server.$canonical.'"/>');
It prints the right canonical, but it also leaves the old canonical link there so that I have 2 canonical links in the header.
How can I change or delete the old canonical link?
I have found the following to work for me with Joomla! 3.2.1. You can directly modify the
$_links
variable in the JHtmlDocument object.
I'm doing a subset of the following in a particular view of my component because the URL that Joomla! is coming up with is not correct.
Hope this helps.
$document = JFactory::getDocument();
foreach($document->_links as $key=> $value)
{
if(is_array($value))
{
if(array_key_exists('relation', $value))
{
if($value['relation'] == 'canonical')
{
// we found the document link that contains the canonical url
// change it!
$canonicalUrl = 'http://www.something.com/index.php/component/my-component-name-here/?view=viewNameHere&parameterNameHere=parameterValueUsedInTheViewRightNow
$document->_links[$canonicalUrl] = $value;
unset($document->_links[$key]);
break;
}
}
}
}
What you probably want to do instead is something like the following:
$doc_data = $document->getHeadData();
$url = JURI::root();
$sch = parse_url($url, PHP_URL_SCHEME);
$server = parse_url($url, PHP_URL_HOST);
$canonical = $this->escape($_SERVER['REQUEST_URI']);
$newtag = '<link rel="canonical" href="'.$sch.'://'.$server.$canonical.'"/>'
$replaced = false;
foreach ($doc_data['custom'] as $key=>$c) {
if (strpos($c, 'rel="canonical"')!==FALSE) {
$doc_data['custom'][$key] = $newtag;
$replaced = true;
}
}
if (!$replaced) {
$doc_data['custom'][] = $newtag;
}
$document->setHeadData($doc_data);
This will grab all of the current head data from the document, including the canonical link that you want to replace. It will search through the custom set (where I'm guessing this will be) and if it finds it, replace it with yours. If it doesn't find it, then it tacks it on at the end. Just in case.
Potential problems with this that I can see right away:
If the tag contained rel='canonical' with single quotes it would not be found, so you may have to adjust that.
The tag may have been placed in a different section of what I've termed $doc_data. You may want to do a var_dump($doc_data}; to confirm the location of the variable in this array.

How to get Response of REST API in JSON format by Default in Magento

In magento as we use the REST url to access the data,as http://localhost/magemto/api/rest/products it returns in XML format.
But as my team requirement, I should send the data in JSON format to access AJAX calls easily.. I have used REST client to include a header as 'Content-Type:appilcation/json'.. Then it returns in JSON format.. But I want it as defaultly by the magento API..
Hey, I do have a solution for this, I would like to share with you.
First go to your magento root folder then go to following path
\app\code\core\Mage\Api2\Model\Request.php
Go to the method getAccepTypes() and change with this code below it will fulfill your requirement.
public function getAcceptTypes()
{
$qualityToTypes = array();
$orderedTypes = array();
foreach (preg_split('/,\s*/', $this->getHeader('Accept')) as $definition) {
$typeWithQ = explode(';', $definition);
$mimeType = trim(array_shift($typeWithQ));
// check MIME type validity
if (!preg_match('~^([0-9a-z*+\-]+)(?:/([0-9a-z*+\-\.]+))?$~i', $mimeType)) {
continue;
}
$quality = '1.0'; // default value for quality
if ($typeWithQ) {
$qAndValue = explode('=', $typeWithQ[0]);
if (2 == count($qAndValue)) {
$quality = $qAndValue[1];
}
}
$qualityToTypes[$quality][$mimeType] = true;
}
krsort($qualityToTypes);
foreach ($qualityToTypes as $typeList) {
$orderedTypes += $typeList;
}
unset($orderedTypes);
$orderedTypes=Array
("application/json" => 1);
return array_keys($orderedTypes);
}
Hope this help you.

TYPO3 Extbase: How to render the pagetree from my model?

I want to create some kind of sitemap in extbase/fluid (based on the pagetree). I have loaded the pages table into a model:
config.tx_extbase.persistence.classes.Tx_MyExt_Domain_Model_Page.mapping.tableName = pages
I have created a controller and repository, but get stuck on the part wich can load the subpages as relation into my model.
For example:
$page = $this->pageRepository->findByPid($rootPid);
Returns my rootpage. But how can I extend my model that I can use $page->getSubpages() or $page->getNestedPages()?
Do I have to create some kind of query inside my model? Or do I have to resolve this with existing functions (like the object storage) and how?
I tried a lot of things but can simply figure out how this should work.
you have to overwrite your findByPid repository-method and add
public function findByPid($pid) {
$querySettings = $this->objectManager->create('Tx_Extbase_Persistence_Typo3QuerySettings');
$querySettings->setRespectStoragePage(FALSE);
$this->setDefaultQuerySettings($querySettings);
$query = $this->createQuery();
$query->matching($query->equals('pid', $pid));
$pages = $query->execute();
return $pages;
}
to get all pages. Than you can write your own getSubpages-method like
function getSubpages($currentPid) {
$subpages = $this->pagesRepository->findByPid($currentPid);
if (count($subpages) > 0) {
$i = 0;
foreach($subpages as $subpage) {
$subpageUid = $subpage->getUid();
$subpageArray[$i]['page'] = $subpage;
$subpageArray[$i]['subpages'] = $this->getSubpages($subpageUid);
$i++;
}
} else {
$subpageArray = Array();
}
return $subpageArray;
}
i didn't test this method, but it looks like this to get alle subpages.
i wonder that i couldĀ“t find a typo3 method that return the complete Page-Tree :( So i write a little function (you can use in an extbase extension), for sure not the best or fastes way, but easy to extend or customize ;)
first you need an instance of the PageRepository
$this->t3pageRepository = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Frontend\\Page\\PageRepository');
this->t3pageRepository->init();
make the init, to set some basic confs, like "WHERE deletet = 0 AND hidden = 0..."
then with this function you get an array with the page data and subpages in. I implement yust up to three levels:
function getPageTree($pid,$deep=2){
$fields = '*';
$sortField = 'sorting';
$pages = $this->t3pageRepository->getMenu($pid,$fields,$sortField);
if($deep>=1){
foreach($pages as &$page) {
$subPages1 = $this->t3pageRepository->getMenu($page['uid'],$fields,$sortField);
if(count($subPages1)>0){
if($deep>=2){
foreach($subPages1 as &$subPage1){
$subPages2 = $this->t3pageRepository->getMenu($subPage1['uid'],$fields,$sortField);
if(count($subPages2>0)){
$subPage1['subpages'] = $subPages2;
}
}
}
$page['subpages'] = $subPages1;
}
}
}
return $pages;
}

Why does a form submit only refresh the page when I turn on codeigniter caching?

probably a noob question but I am not sure what is going on. Here is the function from the controller...
function product ($product_id = NULL)
{
if ($this->input->post())
{
$pcs = array();
$pcs[] = $this->input->post('product_id');
$pcs[] = $this->input->post('styles');
$build = implode('-', $pcs);
redirect('seatcovers/configure/'.$build);
}
elseif ($this->_checkID('id','products',$product_id))
{
$data['product'] = $this->model_products->getProductRow($product_id);
$data['styles'] = $this->model_products->getStyles($product_id);
$data['images'] = $this->model_products->getImages($product_id);
$tags['title'] = 'title';
$this->load->view($this->session->userdata('language').'/includes/view_header',$tags);
$this->load->view($this->session->userdata('language').'/products/view_product',$data);
$this->load->view($this->session->userdata('language').'/includes/view_footer');
}
else {
redirect('seatcovers');
}
}
Not sure what I'm doing wrong? Does caching not work when their is a form?
Yes, caching is done on URI level means, when a URL is cached in Codeigniter then it will display the cached page and will not execute your controller.

Resources