I made a "My bookmarks" tab on the user profile page using Views. The tab shows nodes the user has flagged.
However - "My bookmarks" should only be visible on the user's own profile page and at the moment the "My bookmarks" tab is visible on every profile a user visits. How do I check whether the current user matches the profile being viewed? I tried that from the View interface, but the access permissions don't have any options that work.
EDIT:
I think it is this code, but I still need some guidelines as to how to implement that:
<?php
global $user;
if (arg(0) == 'user' && $user->uid == arg(1)){
return TRUE;
}
else {
return FALSE;
}
?>
I also found this module, I think it helps a lot Views Access Callback
I managed to solve this using the code and module from above.
The custom module contains this code
<?php
function MYMODULE_views_access_callbacks() {
return array(
'MYCALLBACK_user_has_access' => t('User can only see tab on his own profile'));
}
function MYCALLBACK_user_has_access() {
global $user;
if (arg(0) == 'user' && $user->uid == arg(1)){
return TRUE;
}
else {
return FALSE;
}
}
?>
The Views Access Callback module adds your callback to the Views interface and from there, you can use it for your own view.
Related
Ive written a provisioning module for WHMCS and attached it to a product but the module presents 6 buttons, Create, Suspend, Terminate, Change Package, and Change Password. I dont need these buttons as they make no sense for my module, instead I have some custom ones that do what I need, how do I remove these buttons from the product page?
Can't find anything on the WHMCS documentation to describe how to remove or even change the text of the buttons.
Did you check Custom Functions in the Provisioning Modules documentation?
To add client area buttons/functions:
function mymodule_ClientAreaCustomButtonArray() {
//Add or remove items as required
$buttonarray = array(
"Reboot Server" => "reboot",
"Custom Label" => "customlabel",
);
return $buttonarray;
}
//customlabel implementation
function mymodule_customlabel($params) {
# Code to perform customlabel action goes here...
if ($successful) {
$result = "success";
} else {
$result = "Error Message Goes Here...";
}
return $result;
}
One User has One Profile(obviously). How do I design the logic behind this?
I have two tables namely "tbl_users" and "tbl_profile".
When I open the profile page, I should be able to see the "Create
Profile" button only if the profile does not exist.
Once the profile has been created by the user, "Create Profile"
button should not appear next time.
Please describe me in detail how the columns of both tables are linked and what changes I have to include in both the models and other changes too.
Thank you.
In your controller you could write something like this:
$user = User::findOne(Yii::$app->user->id);
$profile = $user->profile;
return $this->render('view', ['user' => $user, 'profile' => $profile]);
Then in your view
if(null !== $profile) {
/*show your button here. It's going to work once because...*/
} else {
/*...here you could show form to create your profile*/
}
In your User model use code like this
public function getProfile()
{
return $this->hasOne(Profile::className(), ['id' => 'profile_id']);
}
This is just an example to give you idea.
I have a simple controller action that creates a Guest record and renders a template.
// First bind the form to our Guest:
$form->bind( $_POST, $guest );
// Validate and save, or show error messages
if( $form->isValid($_POST, $guest) ) {
if( $guest->save($_POST) ) {
$this->view->setMainView( 'confirm' );
}
}
This works fine before I add any mailer stuff. However, when I add an event handler inside the Guest model which happens to render a template, the controller renders a WHITE SCREEN OF DEATH instead of my confirm template.
In Guest model:
public function afterCreate() {
return GuestMailer::sendEmailConfirmation( $this );
}
In GuestMailer class:
public static function sendEmailConfirmation( $guest ) {
// create/configure $email message
$view = $guest->getDI()->get('simpleView');
$view->render( // Works without this call...
'confirmation_email',
array( 'guest' => $guest )
);
$content = $view->getContent();
$email->content( $content );
return $email->send();
}
Note that when I remove the above call to render(), the confirm template is rendered successfully.
I thought components in Phalcon were supposed to be highly decoupled? Why is rendering a completely different template causing my controller's view to get messed up? How can I avoid this?
I think this problem is caused by a peculiar configuration of the templating service, in a normal workflow it doesn't causes issues, they appears when you need to render "manually" a template as in your case, you can refer to this PhalconPHP forum discussion linked, in particular the answer refered by the link anchor:
http://forum.phalconphp.com/discussion/109/manually-render-separate-file-template-#C12015
I am a newbie interested to know are there any extension to count views on click of a button as to know no. of registered users or visiters to web page to know the view count on click of a image is there any extension.
Plz let me know if any
thanx :)
I think , there is no need of any extension. Make a Ajax call on click button or image you are interested.
Improved:
I supposed you have Site as controller and index as action. then, please keep this code on views/site/index.php .
Yii::app()->clientScript->registerScript('logo_as_image_script', '$(document).ready(function() {
$("#logo_as_image").click(function() {
$.post("'.Yii::app()->createAbsoluteUrl('site/index').'",
{
clicked: "1"
},
function(data, status) {
alert("Data: " + data + "\nStatus: " + status);
});
});
});');
Yii::app()->clientScript->registerCoreScript('jquery');
echo CHtml::image(Yii::app()->baseUrl . '/images/logo.png', 'Logo as Image', array('id' => 'logo_as_image'));
And, keep this code on SiteController.php .
public function actionIndex()
{
// keep record of data ; do more filtering ; other manupulation
if(isset($_POST['clicked'])){
$nextCount = Yii::app()->user->getState('clickCount')+1;
Yii::app()->user->setState('clickCount',$nextCount );
echo $nextCount;
Yii::app()->end();
}
#other codes here.
$this->render('index');
}
Lets assume that you want to store how many registered users have accessed the page at :
www.something.com/something/someaction
then visit the controller and add the code like so :
public function actionSomeAction()
{
$model = new CountDbModel();
if(!Yii::app()->user->isGuest){
$model->page = 'This page name here.';
$model->user_id = Yii::app()->user->id;
$model->count = #Add the value here.
#You other code here....
$this->render('whateverView',array('model'=>$blah));
}
}
I hope it helped.
I have an MVC project with three roles: Users, Account Managers, and Administrators.
Administrators have their own MVC Area where they have full control over Users and Account Managers. I'm trying to implement functionality to allow Administrators to view the site as any User or Account Manager.
In the Admin Area of the site, I have a View of a list of Users and Account Managers. The list contains a "View Site As User" button for each record.
I have never done anything like this before, but the ViewAs Controller Action is currently set up to create a Session with the selected User's information, like so:
ViewBag.SiteSession = Session["SiteSession"] = new SiteSession()
{
ID = user.ID,
AccountID = user.AccountID,
DisplayName = user.DisplayName,
IsManager = user.IsAdmin,
IsAdmin = false
};
The View relevant to this Action has the Model defined as a string, and nothing else but an iframe with the Model as the src attribute, like so:
#model string
<iframe src="#Model" >
</iframe>
What I'm trying to do is render whichever portion of the site was requested in this iframe. When an Administrator clicks "View As User," I'd like to direct to Home. The URL is generated through this call:
Url.Action("Index", "Home", new { Area = "" }));
The Area is set to nothing to avoid rendering the Admin Area's Home.
Currently, this is not working. I don't know where to even begin, minus what I already have.
I'm looking for any suggestions. All help is greatly appreciated, as this doesn't seem like an easy task.
If you don't know how to help, it would also be appreciated if you could direct this question to somebody that can.
Again, thanks in advance.
The way that I've done this in the past has been to use the concept of an an actual user and an effective user. Most display actions use the effective user to generate their content. Typically I've implemented it as "impersonation" rather than "preview" so the user is actually navigating the site as the user rather than displaying in a separate window. In this case I simply set both in the current session. Things that require admin permission (like switching to/from impersonation) obviously use the real user.
If you wanted to do preview then I'd think about using a parameter on each request to set the effective user. The code would need to understand to add this parameter to all links so that you could navigate in the iframe without messing up navigation in the original interface.
As for removing the area from the url, I think what you have (setting to the empty string) should work. If it's not working you might want to try lowercase area, Url.Action("Index", "Home", new { area = "" }). I'm pretty sure that the RouteValueDictionary that gets created under the hood uses a case insensitive key comparison, though, so it shouldn't matter.
For this task, I ended up creating a separate controller, ViewAsController, which had a controller-wide [Authorize] attribute that only allowed users with the Admin role to access its actions.
In the Start action, a Session object containing the selected User's information is created, like so:
[HttpGet]
public ActionResult Start(int id)
{
var user = db.Users
.First(u => u.ID == id);
Session["SiteSession"] = new SiteSession()
{
//Session data...
};
return PartialView("_IFrame");
}
This Action returns a Partial View that I ended up displaying in a jQuery UI modal dialog window.
Here's the code for that Partial View:
#{
ViewBag.SiteSession = (SiteSession)Session["SiteSession"];
}
<h2>Viewing Site As #ViewBag.SiteSession.DisplayName</h2>
<div>
<iframe src="#Url.Action("Index", "Home", new { Area = "" })"></iframe>
</div>
As you can see, it's extremely bare, and that's exactly what it needs to be. The <iframe> acts as a browser in a browser, allowing the Admin user full access to whichever Actions the selected User would.
For the sake of detail, here's the jQuery that creates the dialog and opens it:
$(function () {
$("#viewAsDialog").dialog({
modal: true,
autoOpen: false,
resizable: true,
draggable: true,
closeOnEscape: false,
height: $(window).height() * .9,
width: 1000,
closeText: '',
close: function () {
$.post("#Url.Action("End", "ViewAs", new { Area = "Admin" })")
.success(function (result) {
});
}
});
});
function viewAs(result) {
$("#viewAsDialog").html(result);
$("#viewAsDialog").dialog("open");
}
You can see here that the dialog is initialized on document-ready, and is not opened until the AJAX call that retrieves the Partial View is successfully completed.
Once the Admin closes the dialog, the server calls the End action in the ViewAs Controller, destroying the session:
[HttpPost]
public ActionResult End()
{
Session["SiteSession"] = null;
return new HttpStatusCodeResult(System.Net.HttpStatusCode.OK);
}