I have an application where I need to redirect to a website ( example below). My issue is that the cakephp3 application is embedded in a wordpress iframe and for some reason the below command executes inside an iframe so i have a webpage within a webpage. How can i redirect to a webpage outside an iframe?
//controller
if ....
return $this->redirect('http://www.xxxxxx/thank-you-application/');
What goes on in Vegas, stays in Vegas
What goes on in an iframe, stays in that iframe
I don't think what you want is possible with PHP (and any PHP framework),
Maybe with getting the content of the page that you want to load inside the iframe with:
$http = new Client();
$response = $http->get('http://example.com');
$content = $response->body();
and put the $content in the view in the "top level page / mean not inside iframe" (like they do in financial website), but i'm not sure of the exact way.
the easiest solution is to send in your controller a value ($redirect = true) to the view that will say: "Hey! view, plz open this link to the top level window! / mean outside the iframe".
write something like this in your view (or template):
<!-- ... -->
<?php if($redirect) : ?>
<body onload="javascript:window.top.location.href='<?= $this->Url->build([
"controller" => "Pages",
"action" => "display",
"thank-you"
]) ?>'";>
<?php else: ?>
<body>
<?php endif; ?>
<!-- ... -->
Hope it helps
Related
I'm trying to make a global variable called theUser which contains the userinfo if logged in.
I have tried putting this in my SPA php file:
app.value('theUser', '<?php echo Auth::user(); ?>');
And it works but only after refreshing page. (Login happens via angularjs logic + a $http request to auth/login which returns userinfo if logged in)
In my angular auth app, I have done this:
var login = $http.post("auth/login", sanitizeCredentials(credentials)).success(function(data) {
theUser = data;
$rootScope.theUser = theUser;
});
And that works, but only when the user logs in. If I refresh, theUser is empty. And I can't get these two solutions to work together. I probably need another approach.
All I want is an user variable that I can access from anywhere in my app,
which is set if the user logs in, or have been logged in before. Using Laravel 5.1.
Here is my auth app service js: http://pastebin.com/HcdLaZcD
How can I make this work?
Why dont you use PHP-Vars-To-Js-Transformer by Laracasts. Then whenever a User logs in, you could set a Session variable auth_user and then get that variable to JavaScript as shown below (in your Laravel AuthController#login):
...
\Session::put('auth_user', \Auth::user());
JavaScript::put([
'theUser' => \Session::get('auth_user')
]);
...
And when the User logs out: \Session::forget('auth_user');
theUser variable will be available anywhere in your JavaScript (or you can Namespace it also, check the Github link above).
on top of the page under script tag
window.user = <?php echo Auth::user(); ?>
and
app.value('theUser',window.user);
app.run(function ($rootScope, theUser) {
$rootScope.theUser = theUser;
});
For accessing the logged in user from your JavaScript files, you may try something like this (Create a view composer, also layouts.master dictates layouts/master.blade.php):
View::composer('layouts.master', function($view) {
$user = null;
if(Auth::check()) {
$user = Auth::user();
}
$view->with('authUser', $user);
});
In the master layout try this (So User variable will be available as JS object if the user is logged in):
<head>
<script>var User = {{ $authUser or 'undefined' }}</script>
</head>
This is just an idea, implement it according to your need. Also, you may use a namespace like App.user. I wrote an article about this lasr year, you may
check it here. Btw, it was for Laravel 4.x.
.
We have made use of html5 local storage to overcome this once the user is logged in, you just put the user's info on html5's local storage (works on all browsers, even mobile).
It has some drawbacks which you have to overcome, and also have some control on your routes filters to avoid someone loading page they shouldn't be allowed to see.
But I'm afraid my answer applies better to our solution and I don't think this answer is perfect but might guide you in a better solution. Our app publishes an API for angular's use and this angular is somewhat empowered with some extensions to ease routing.
In CakePHP 2.x you could do
AuthComponent::user()
in View to get data from Auth component. In CakePHP 3.0beta3 it throws:
"Error: Class 'AuthComponent' not found"
Is there a simple way to get data from AuthComponent in View?
In View:
$this->request->session()->read('Auth.User.username');
In Controller
$this->Auth->user('username');
You should have never used the AuthComponent in views in the first place.
It is better to either pass down the data from the controller to the view and access that, or better yet, use a AuthHelper to wrapper-access it easily (by reading from the session there for example).
An example would be AuthUser (
https://github.com/dereuromark/cakephp-tools/blob/master/src/View/Helper/AuthUserHelper.php ):
$this->AuthUser->id();
$this->AuthUser->user('username');
etc
The helper way doesn't require additional use statements in your view ctps and keeps them lean.
It also prevents notices when trying to access undefined indexed automatically.
if ($this->AuthUser->user('foobarbaz')) { // no error thrown even if it never existed
}
Cake 3.5
In AppController:
public function beforeRender(Event $event) {
....
$this->set('Auth', $this->components()->__get('Auth'));
}
In .ctp template:
<?php if (!$Auth->user()) { ?>
<a class="login" href="<?php echo $this->Url->build($Auth->getConfig('loginAction')); ?>">Login</a>
<?php } else { ?>
<div class="name"><?php echo h($Auth->user('name')); ?></div>
<?php } ?>
The AuthComponent is deprecated as of 4.0.0 and will be replaced by the authorization and authentication plugins.
Authentication plugin has built in View Helper.
I've got a problem showing $this->Session->flash();. In my controller just for testing purpouse I set a session flash and then I throw a new Exception, but in my view the session flash is not showing.
I'm throwing an error because I'm using ajax to submit a form and dynamically uptade my view. Is there a way to upcome this without droping the ajax?.
edit
in my controller
$this->Session->setFlash(__('Error, try again'), 'flash_foundation_good');
throw new InsertException(__('Error, try again.'));
in my layout
<div class="inner-wrap">
<?php echo $this->Session->flash(); ?>
<?php echo $this->fetch('content'); ?>
<a class="exit-off-canvas"></a>
</div>
In my view
As I said before, I'm using an ajax call here is a little of it. (just the submit button)
echo $this->Js->submit('Save',
array(
'id'=>'submit-ajax',
'update' => '#myModal',
'before'=>'before();',
'complete'=>'reset();',
'success'=>'success();',
'error'=>'nope(XMLHttpRequest);',
'div'=>array('class'=>'row'),
'class'=>'button',
'style'=>'margin: 0 auto; display: block;'
)
);
echo $this->Js->writeBuffer();
I just work around the session flash using the error method, and dynamically show what I want, but still I want too know how to make appear the session flash ):
I'm just getting started with cakePHP, and things aren't going so well so far.
I have a controller that handles confirming user emails. On registration the user is sent an email with a confirmcode in a link. Depending on the confirm code they give, the controller gives different text responses. One of these responses includes a hyperlink in order to log in.
I'm trying to use the Html helper, but although I've loaded it in $helpers at the top of the class, I an only make it work if I then use App::import, and then instantiate it.
It all seems overkill to simply make a hyperlink! How many times do I have to load the same class?
Wherever I look on the web it keeps telling me it's a bad idea to use a helper in a controller, but how else am I supposed to get the link made?
So I have
var $helpers = array('Html');
at the top of the controller, and:
if (isset($this->User->id)) { // Check the user's entered it right
// Do some stuff to remember the user has confirmed
// This is to load the html helper - supposedly bad form, but how else do I make the link?
App::import('Helper', 'Html');
$html = new HtmlHelper();
$this->set('message', __("Your email address has been confirmed.", TRUE)." ".$html->link(__("Please log in", TRUE), array('controller' => "users", 'action' => "login" )));
} else {
$this->set('message', __("Please check your mail for the correct URL to confirm your account", TRUE));
}
in the controller's confirm method and
<div>
<?php echo $message;?>
</div>
in the view to output the resulting message
Surely I'm going wrong somewhere - can anyone explain how?
You're not supposed to use Helpers in the Controller. As #Lincoln pointed out, you should construct the link in the View. You may construct the URL in the Controller, since a URL is basically data, but a link is a very medium-specific (HTML) implementation of a URL.
Either way, you'll need to create a full URL (including host) if you want to send it in an Email. The most universal way is to use Router::url:
$fullUrl = Router::url(array('controller' => ...), true); // 'true' for full URL
Do this in either the Controller or the View. For creating a link, use this in the View:
echo $html->link('Title', $fullUrl);
The idea is that all the data you need to render the page is sent to the view with set, then any conditional logic or formatting is done in the view with helpers, so send whole query results when appropriate (suppose you need to alter a link to include the user's screen name, you'll have it handy).
in controller action
$this->set('user', $this->User);
in view (this is slightly different depending on if your in <= 1.2 or 1.3
if ($user->id) //available because of Controller->set
{
//1.2
$link = $html->link(__("Please log in", TRUE), array('controller' => "users", 'action' => "login" ));
//1.3
$link = $this->Html->link(__("Please log in", TRUE), array('controller' => "users", 'action' => "login" ));
echo __("Your email address has been confirmed.", TRUE)." $link";
}
else
{
$this->set('message', __("Please check your mail for the correct URL to confirm your account", TRUE));
}
What you are trying to do should be done with the SessionComponent. $this->Session->setFlash('your message here');
and in your layout with the session helper put $this->Session->flash();
About your wanting urls in the controller, Router::url is correct as deceze said, but there is no use for it there as you should not be building html in a controller.
what you want to do it use the session::setFlash() method above and then redirect them using
$this->redirect(array('controller' => "users", 'action' => "login" ));
The problem is i want to call the index function, i need it to render the view and then the
afterFilter to redirect again to the index function and do the same.. Like a loop, the problem is it doesnt render it, ive tried using $this->render('index') but it doesnt work and also other things..
PS: I didnt include all the code that i have in index, because its pointless, doesnt render with or without it, just included the things i needed for the view.
function afterFilter()
{
if ($this->params['action'] == 'index')
{
sleep(3);
$this->redirect(array('action'=>'index',$id), null, true);
}
}
THE FUNCTION
function index($ido = 0)
{
$this->set('Operator', $this->Operator->read(null, $ido));
$this->set('ido', $ido);
}
THE VIEW = INDEX.CTP
<legend>Operator StandBy Window</legend>
<?php
?>
</fieldset>
<?php echo $html->link('LogIn', array('controller' => 'operators', 'action' => 'add')); ?>
<?php echo $html->link('LogOut', array('controller' => 'operators', 'action' => 'logout',$ido)); ?>
a function that constantly checks my database for a change, if a change occurs ill redirect, if not i need to have that constant loop of 'checking the database' and 'rendering the view'.
This is not possible entirely on the server with PHP, and especially not with CakePHP's template system. PHP just "makes pages" on the server and sends them to the browser and a linear fashion. If you loop on the server, the content of your page will just repeat itself:
Normal content
Normal content
Normal content
<redirect>
To redirect the client, you need to output headers. The headers need to be output before anything else. If you've already looped a few times and content has already been sent to the client, you can't redirect anymore.
There are two ways:
You just output one page at a time showing the current status, with a meta tag that'll refresh the page every x seconds. This can be rather expensive and annoying though.
Use AJAX and possibly Comet to update the information on the page dynamically in the browser.