Customize pagination links in CLinkPager - yii

I am using CLinkPager and need to customize the pagination links url.
Need to add #test in the url of the pagination links.

You can implement custom class extends CLinkPager and override createPageUrl() mentod there:
class MyLinkPager extends CLInkPager(){
public $linkHash = '';
protected function createPageUrl($page)
{
$url = $this->getPages()->createPageUrl($this->getController(),$page);
if($this->linkHash)
$url = $url.'#'.$this->linkHash;
return $url;
}
}
Put file with this class in extension folder and dont forget add this folder in import in config (main.php):
'import'=>array(
'application.extensions.*',
...
)
And further, for example in CGrigView configuration, set this pager class:
this->widget(
'zii.widgets.grid.CGridView',
array(
'dataProvider' => $dataProvider,
'pager'=>array(
'class'=>'MyLinkPager',
'linkHash'=>'test'
),
...
)
)

Related

Prestashop : Display simple page in Admincontroller (without ObjectModel)

I want to create a simple page in Prestashop back-office. I don't need any ObjectModel.
I've created a new admin Tab. My problem is in AdminController.
You can see the following code : the variables are not transmitted to the template file. I don't understand how to do it.
class AdminAzertyController extends AdminController
{
public function initContent()
{
parent::initContent();
// Le template smarty
$tpl_path = _PS_MODULE_DIR_ .'paniersdegout/views/templates/admin/view.tpl';
$tpl = $this->context->smarty->createTemplate($tpl_path, $this->context->smarty);
$content = $tpl->fetch();
$this->context->smarty->assign('content', $content);
// Le passage de variable
$this->context->smarty->assign('test', 'test');
}
}
To render custom tpl file in the custom controller, you can use smarty to assign content.
For example, if you have to render customtemplate.tpl file of custom module.
public function initContent() {
parent::initContent();
$content = $this->context->smarty->fetch(_PS_MODULE_DIR_ . 'custommodule/views/templates/admin/customtemplate.tpl');
$this->context->smarty->assign(
array(
'content' => $this->content . $content,
)
);
}

Yii2 - Capture paramether from router in beforeAction

Is there a way to capture parameter from router in the beforeAction, so it could be use by all functions in controller?
I have this router:
'http://<user:\w+>.' . $domain . '/<controller:\w+>/<action:\w+>' => '<controller>/<action>',
I want to use as ID in all functions in controller, and make it available without injecting it into the function? Is this possible?
A raw solution can be intercept the $params array inside the bindActionParams:
class ParamController extends Controller {
public $user;
public function bindActionParams($action, $params)
{
if(isset($params['user'])){
// may be some business based on $this or $action
$this->user = $params['user'];
}
return parent::bindActionParams($action, $params); // TODO: Change the autogenerated stub
}
}
Of course you need to extends all your controllers from ParamsController.

Set up link in SilverStripe navigation to automatically download a PDF file

I have some code I'm working on for a PDF download page type in SilverStripe that allows people to upload a PDF file to the backend. In turn, this PDF file is then read into the top navigation as a link that, when clicked, automatically downloads the PDF file.
I have most of the code set up:
<?php
class PDFTemplate extends Page {
public static $db = array(
);
public static $has_one = array(
'PDFFile' => 'File'
);
public static $has_many = array(
);
public function Link() {
return '/home/download?ID=' . $this->ID;
}
public function getCMSFields() {
$fields = parent::getCMSFields();
$fields->addFieldToTab("Root.Main", new UploadField('PDFFile', "PDF File"), "Content");
return $fields;
}
}
class PDFTemplate_Controller extends Page_Controller {
public static $allowed_actions = array (
'download'
);
public function init() {
parent::init();
}
public function download() {
$id = $_GET['ID'];
$obj = DataObject::get_by_id('PDFTemplate', $id);
header('Content-Type: application/pdf');
header('Content-Disposition: attachment;');
header('Pragma: no-cache');
return readfile("");
}
}
But the one thing I'm stuck on at the moment is how to get the url of the PDF file into the readfile() command. $obj right now is being set to get the id of the specific PDF file for the page....so do I need do use something like $obj.URL or $obj.Link in readfile()?
You're requesting a PDFTemplate object at the moment, not a File object so that's a problem - but you shouldn't need to pass an ID to this page to download it anyway because the Page already has that information.
If you don't need to hide the direct URL of the PDF in question, something like this might be a lot easier and offer better performance:
Delete the download() and Link() functions.
In the .ss template for your menu do: <a <% if $PDFFile %>href="$PDFFile.Link" target="_blank"<% else %>href="$Link"<% end_if %>>

Silverstripe assumes SiteTree relation is to Parent?

My (partial) DataObject:
class InternalExternalLink extends DataObject {
private static $db = array(
'ExternalLink' => 'VarChar(256)',
'LinkLabel' => 'VarChar(256)',
"LinkType" => "Enum(array('Internal', 'External','Attachment'))"
);
private static $has_one = array(
'InternalLink' => 'SiteTree',
'Attachment' => 'File'
);
function getCMSFields() {
$fields = new FieldList(array(
$internal = DropdownField::create("InternalLinkID", "Choose a page", SiteTree::get()->map()->toArray())->setEmptyString("-- choose --"),
));
return $fields;
}
Add I add this to Page:
class Page extends SiteTree {
private static $has_many = array(
'Links' => 'InternalExternalLink'
);
function getCMSFields() {
$fields = parent::getCMSFields();
$gridField = new GridField('Links', 'Links', $this->Links(), GridFieldConfig_RecordEditor::create());
$fields->addFieldsToTab('Root.Main', $gridField);
return $fields;
}
The problem is when adding Links via the gridfield it automatically assumes that the Link.InternalLink is the parent page, rather than any page, and hides the page select drop down. E.g. if I am editing the about-us page then every Link dataobject I add via the gridfield automatically sets its InternalLink to the about-us page.
How do I change this assumption to allow me to select any page via the dropdown?
Try this:
1) Give the DataObject a "Parent" relation:
class InternalExternalLink extends DataObject {
private static $has_one = array(
'Parent' => 'DataObject',
'InternalLink' => 'SiteTree',
'Attachment' => 'File'
);
...
}
2) Specify "Parent" in the page's has_many:
class LinkTestPage extends SiteTree {
private static $has_many = array(
'Links' => 'InternalExternalLink.Parent'
);
...
}
The problem here is the relation on InternalExternalLink is to SiteTree whereas you're trying to define a relationship back to it on Page. As there's no has_one from InternalExternalLink to Page, and you're using a slightly older version of 3.1, the default has_one of Parent is looked for.
To solve this, you can either change the InternalLink relation to point to Page instead of SiteTree or use a DataExtension to add the has_many relation on to SiteTree.

how to use SimpleSAMLphp in yii framework?

I have two project in yii framework and I want to use both project using SimpleSAMLphp with SSO. The condition, I need is if I login from the first project, i want access to the second project.
Thank you in advance.
First you load the SAML library by temporarily disabling the Yii autoloader. This is just to let you use the SAML classes and methods:
<?php
class YiiSAML extends CComponent {
private $_yiiSAML = null;
static private function pre() {
require_once (Yii::app()->params['simpleSAML'] . '/lib/_autoload.php');
// temporary disable Yii autoloader
spl_autoload_unregister(array(
'YiiBase',
'autoload'
));
}
static private function post() {
// enable Yii autoloader
spl_autoload_register(array(
'YiiBase',
'autoload'
));
}
public function __construct() {
self::pre();
//We select our authentication source:
$this->_yiiSAML = new SimpleSAML_Auth_Simple(Yii::app()->params['authSource']);
self::post();
}
static public function loggedOut($param, $stage) {
self::pre();
$state = SimpleSAML_Auth_State::loadState($param, $stage);
self::post();
if (isset($state['saml:sp:LogoutStatus'])) {
$ls = $state['saml:sp:LogoutStatus']; /* Only for SAML SP */
} else return true;
return $ls['Code'] === 'urn:oasis:names:tc:SAML:2.0:status:Success' && !isset($ls['SubCode']);
}
public function __call($method, $args) {
$params = (is_array($args) and !empty($args)) ? $args[0] : $args;
if (method_exists($this->_yiiSAML, $method)) return $this->_yiiSAML->$method($params);
else throw new YiiSAMLException(Yii::t('app', 'The method {method} does not exist in the SAML class', array(
'{method}' => $method
)));
}
}
class YiiSAMLException extends CException {
}
Then you define a filter extending the CFilter Yii class:
<?php
Yii::import('lib.YiiSAML');
class SAMLControl extends CFilter {
protected function preFilter($filterChain) {
$msg = Yii::t('yii', 'You are not authorized to perform this action.');
$saml = new YiiSAML();
if (Yii::app()->user->isGuest) {
Yii::app()->user->loginRequired();
return false;
} else {
$saml_attributes = $saml->getAttributes();
if (!$saml->isAuthenticated() or Yii::app()->user->id != $saml_attributes['User.id'][0]) {
Yii::app()->user->logout();
Yii::app()->user->loginRequired();
return false;
}
return true;
}
}
}
And finally, in the controllers you are interested to restrict, you override the filters() method:
public function filters() {
return array(
array(
'lib.SAMLControl'
) , // perform access control for CRUD operations
...
);
}
Hope it helps.
It can be done simply using "vendors" directory.
Download PHP Library from https://simplesamlphp.org/
Implement it in Yii Framework as a vendor library. (http://www.yiiframework.com/doc/guide/1.1/en/extension.integration)
Good Luck :)
I came across an Yii Extension for SimpleSAMLphp in github
https://github.com/asasmoyo/yii-simplesamlphp
You can load the simplesamlphp as a vendor library and then specify the autoload file in the extension.
Apart from the extension you can copy all the necessary configs and metadatas into the application and configure SimpleSAML Configuration to load the configurations from your directory, so you can keep the vendor package untouched for future updates.