I'm using an existing upload script that require user authentication. However since I did not write the upload script, it's nearly impossible for me to read the source code and make it into separate view and controller file. The problem is if the script does not get routed by the bootstrap file, it has no access to the Yii variable and thus user log in information.
I tried to set a custom session variable when the user login. However it work barely because my custom session would expire before the session set by Yii.
Any help would be appreciated.
Because of the way the script is written I've only been able to find one way of doing this. It will involve re-writing some elements of the script.
Save the filemanager in protected/vendors.
You need a controller to handle the routing of the request. This will also give you the access control that you need. Call it FileUpload and create it where you normally create controllers in your project. Right at the start of the controller, before the class is declared, import the fileUpload files from it's previously saved location; Yii::import('application.vendors.*');
You need an action to handle the incoming request. Call this actionIndex. Give it the following code.
public function actionIndex() {
//Start capturing the output from the script
ob_start();
require_once('filemanager/dialog.php');
//Finish capturing output, and save to a variable
$output = ob_end_clean();
$this->render('index', array('output' => $output));
}
Then you need a view file. Call it 'output.php' and it just contains one line; <?php echo $output; ?>
This will render the html generated by the script, and hopefully contain it within your existing template.
Your first problem is that the script sends headers which aren't discarded by ob_start. You will need to delete these from the script. It also starts a session, which will throw an error 'Session already started', which can be cured by changing the first line of config.php to
if(!isset($_SESSION))
{
session_start();
}
Your next problem will be that none of the scripts and stylesheets are loaded, because the vendor hasn't used relative filepaths, and also because you've just deleted the headers. You will need to re-write lots of the script to include the necessary files. Fortunately, you now have access to Yii functions, so can use the asset manager to publish all the js and css files needed by the script.
Your final (hopefully!) problem will be the urls used by the script page. Currently they are all pointing to files within the script. You will need to rewrite these to use Yii routing. Fortunately, inside the main file dialog.php you should have access to all the normal Yii functions, so you can set $baseUrl as $this->createUrl() etc. If you need to add extra actions to the controller you can follow the pattern above to call other files, like the upload.php file in the script.
Hope that all works for you!
You are using a Framework with mvc pattern so controllers are preferred way to route requests .As per your problem i would suggest you to use htaccess file to do the routing to the required file and handle other files by Yii
copy code from existing source to new Yii Controler/Action ... done :D
Related
I'm trying to make a fiddlejs.
The Code use a VueJS plugin called VueDragula, inside the code, I have:
let VueDragula = require('../vue-dragula');
Vue.use(VueDragula);
So, I uploaded vue-dragula.js to my own server, and added it to external resources, and delete the 2 lines, but now, it says
VueDragula is not defined
I also tried to include directly the content of vue-dragula inside the JS, but happened the same thing.
How should I do that???
I want to insert from Controller in the end of some view's code like this
"<"script> setInterval(function(){ alert("Hello"); }, 3000);"<"/script>
How to do this?
There's multiple ways to do this in PhalconPHP. Depending on your needs, you might be able to get away with just:
$js='setInterval(function(){alert("Hello");},3000);';
$this->view->js=$js;
then from the view, you'd do:
<script><?php echo $js; ?></script>
If you need to insert the JavaScript into your top-level index.phtml from a nested view, the way to accomplish this is to first edit your ControllerBase.php and define a new collection:
$this->assets->collection('footer');
Then add a reference to the footer collection from your top-level index.phtml file:
<body>
<?php echo $this->getContent(); ?>
<?php $this->assets->outputJs('footer'); ?>
</body>
You could also use output('footer') instead if you just wanted a dynamic place in the document you can insert HTML of any kind. Note that a collection specializes in managing CSS and JavaScript, hence the outputJS method, but can also handle miscellaneous code for other purposes. There's also outputCSS, outputInlineJs, outputInlineCss, outputInline, and simply output. See:
http://php-phalcon-docs.readthedocs.org/en/latest/api/Phalcon_Assets_Manager.html
Then edit your ControllerBase.php to initialize the asset to an empty collection:
$this->assets->collection('footer');
(if you skip this step, your code will see errors if your top-level index.phtml file tries to output the contents of a non-existent collection if you never write to it, so always initialize it to an empty collection so it exists.)
Finally, from the controller you want to use, you'd do:
$this->assets->collection('footer')->addInlineJs($js);
where $js is your inline JavaScript, excluding the script tags.
You can also work with external JavaScript files by using
->addJs(...). By default it will be relative to your application directory, inserting a / automatically. If you dislike this functionality, you can set the second parameter to false then it will allow you to specify your own leading / or point your resources at another domain.
As far as the assets you can add to a collection, see:
https://docs.phalconphp.com/en/latest/api/Phalcon_Assets_Collection.html
Note that you can also add assets to your collection from your view and the changes would still appear in your top-most index.phtml.
It is also worth noting that you don't need to actually use collections, you can simply use assets without a collection, but I think collections are more powerful in that you get to name them so there's another level of separation in case you need to manage more than one kind of collection of data.
In terms of what you're trying to accomplish, if you're just trying to give the user a message, this is what Phalcon's flash is for, not to be confused with Adobe Flash which is for playing videos. Phalcon's flash is for flashing messages to the user such as error messages, or your form submit successfully kind of messages. See:
https://docs.phalconphp.com/en/latest/reference/flash.html
If you're still confused what flash is, a demo of what it's output is, you can see in the screenshot here: https://docs.phalconphp.com/en/latest/_images/invo-2.png
That is output of ->error(...) and ->notice(...) respectively. The flash component keeps track of a collection of the messages you'd like to show the user. Then once you're ready to display them to the user you'd call:
<?php echo $this->flash->output(); ?> from your view. It is best to make this call from your top-most template or a template which is always included in your top-most template such as your navigation template so you can easily display messages to the user. It is also useful for debugging. I'd suggest using twitter bootstrap for styling the flash output.
Some sample applications which you might find useful:
https://github.com/phalcon/invo
https://github.com/phalcon/vokuro
https://github.com/phalcon/website
https://github.com/phalcon/forum
Further reading:
https://docs.phalconphp.com/en/latest/index.html
I want to create several javascript function that will be needed on different pages. Most will be relevant only to one page, but some to several. I know if I add general conversion functions, it would be a good idea to just create a new javascript file and put all these generic functions into that one file. Bringing me to my first question:
Where would you store the generic javascript file? In "protected"? Which subfolder?
Then, I need to address the placement of other javascript code.
If I have javascript that will only be used on one page, should I use this technique or should I stick to a similar approach as above?
The emphasis is on doing it correctly. I want to fall exactly in line with the yii framework.
store your generic javascript file in your_app/js folder
i.e js folder is at same level to protected.
if js is only used on one page than it will be better not to use generic file.
The best way to have you generic js code into /js/ or similar named folder under root of your app code. Personally I would separate my custom code files into one other subdirectory /js/custom/ and /js/vendors/ where in this vendor folder you can put ready js code such as jquery plugins etc.
Also don't forget to set this path to config file like this:
'components'=>array(
'clientScript' => array(
'coreScriptUrl' => 'path/to/js/lib/dir',
'enableJavaScript' => true,
),
),
where path/to/js/lib/dir is your final js folder name path
I am using the cookbook article from symfony.com to implement a file upload option for images.
Now I want to load up other images to the entity.
The default strategy for editing is:
1. Fetch out of DB
2. Inject into Form
3. Persist
Somehow this strategy doesn't work anymore when using file uploads (doctrine doesn't execute the events)
What else could I do to make the articles with picture editable?
The cookbook does not handle updates, in particular in the case where only the file changes.
In this case, the PreUpdate event is not triggered, so you need to trigger $entity->preUpload() manually before the $em->persist($entity), so that the file upload gets handled in any case (preUpload will alter $entity->path so the persisting will occur)
If you change only the upload field the lifecycle not run the upload method, In the cookbook is reported the solution in a quote box as below:
The PreUpdate and PostUpdate callbacks are only triggered if there is
a change in one of the entity's field that are persisted. This means
that, by default, if you modify only the $file property, these events
will not be triggered, as the property itself is not directly
persisted via Doctrine. One solution would be to use an updated field
that's persisted to Doctrine, and to modify it manually when changing
the file.
add a dummy field to update in the controller before persist event as suggest by this duscussion:
https://github.com/symfony/symfony-docs/pull/564
public function setFile(UploadedFile $file)
{
$this->file = $file;
$this->updatedAt = new \DateTime();
}
I have was in similar situation.
I try to edit existing record in database with path to the file.
When i edit record i must upload new file, what is not comfortable for users.
In my solution i use variable tmp file for file hash and variable file name.
All needed operation i made in Action edit class.
Full example action class in bellow link
https://github.com/marekz/php_examples/wiki/Symfony-how-to-edit-attachment-form
I just started using Yii, coming from Codeigniter (CI). I'm trying to set up a situation where the application will check a users credentials before they can even access the site. In CI, I would create a parent controller, put my checks in there, and then inherit that parent controller. I've been trying to do the same thing with Yii, but with no luck.
I first created an init() method (for some reason I can't put the code in a __construct() method). I then perform my check, which works fine. I can throw a new CHttpException, but that looks ugly. How do I use Yii's built in error handling to accomplish what I want to do?
For simple login rules you should just implement the 'accessControl' filters from Yii see Yii documentation on authorizations.
Another way would be to throw the Exception like you already did, and write custom Http error views, place it in the yerfolder/protected/views/system/ (see the yii/framework/views directory for examples)
I solved this by sending the error to the site/error view and then calling Yii::app()->end() to keep the child controllers from loading.