Yii: Creating a Demo Site Without Replicating the Code Base - php

I need to set up a demo site for users to try a web app before signing up. The demo would be based on production code, however, it would require minor code changes: connection to a demo database, automatic creation/login of a new guest account for each user, etc.
The obvious solution is to replicate my code base as a second demo website and edit as necessary. Keeping the demo code in sync with production code is easy enough by adding a branch in subversion. I'm less than thrilled, however, at the prospect of having to do two updates on my server (production and then demo) every time I push code from development to production.
Initially I thought I might be able to replicate the website through a module. It's unclear if this is possible, however.
Is there a mechanic in Yii to execute an altered version of a website (config file and selected controllers)?

Never do before, so just an idea
solution with few files in other dir
create a separate a demo dir and map it on your demo URL
In this dir put this index.php (may be your .htaccess too)
<?php
$yii=_PRODUCTION_PATH_.'/framework/yii.php';
$config_prod=_PRODUCTION_PATH_.'/protected/config/main.php';
$config_demo=dirname(__FILE__).'/demo_main.php';
require_once($yii);
$config = CMap::mergeArray($config_prod,$config_demo);
Yii::createWebApplication($config)->run();
the demo_main.php override the classes (user, db) to manage a better demo experience:
<?php
return array(
'basePath'=>_PRODUCTION_DIR_.DIRECTORY_SEPARATOR.'..',
'components'=>array(
'user' => array(
// here you override the user class with a DEMO only user
'class'=>'DemoUser',
)
),
solution with all files of prduction site in a different dir
Here follows the index.php in root dir
<?php
$yii='../framework/yii.php';
$configMain = include dirname(__FILE__).'/protected/config/main.php';
$configProd = include dirname(__FILE__).'/protected/config/production.php';
$configDemo = include dirname(__FILE__) . '/protected/config/demo.php';
require_once($yii);
// for the demo version
// instead of the comment can be an *if* or any solution to manage 2 configs
//$config = CMap::mergeArray($configMain,$configProd);
$config = CMap::mergeArray($configMain,$configDemo);
Yii::createWebApplication($config)->run();
demo.php is analogue to "demo_main.php" overridig classes and configs for the demo version of the site.

The testdrive demo app is configured for this - after you install, note the separate index-test.php, and protected/config/test.php.
Unlike #IvanButtinoni's suggestion, you'll need to access index-test.php, instead of index.php, so you may need to modify your .htaccess if you're using clean URLs to allow access to index-test.php.
When I do this, I usually write a custom init in the base controller.php:
public function init() {
// use test layout if using test config
if (isset(Yii::app()->params['test'])) {
$this->layout='//layouts/test';
}
parent::init();
}
Obviously, I have a test parameter in my test.php . . .
The only difference in my two layouts is that one sets the background color to be a bright yellow, just so it's very clear you're on a test site.

If I have understood well (according to the comment answers to original post) then There are several ways. Here is a link that I think can help great deal. It helped me set up and may be will help you!
In Yii 2 it will be inherently supported
http://www.yiiframework.com/wiki/33/

Related

CKFinder 3 upgrade difficulty

I'm following the CKFinder 2 to 3 upgrade guide and it's not making much sense. In CKFinder 2, the PHP code provided could be used to generate the JS snippet with appropriate config and params, like this:
require_once 'ckfinder/core/ckfinder_php5.php';
$finder = new CKFinder() ;
$finder->SelectFunction = 'ShowFileInfo' ;
$finder->DisableThumbnailSelection = true;
$finder->RememberLastFolder = true;
$finder->Id = $name;
$finder->StartupFolderExpanded = true;
$finder->Width = $width;
$finder->Height = $height;
echo $finder->CreateHtml();
This code picks up the config and incorporates it into the generated JS.
In 3 this seems to have disappeared entirely - the upgrade guide describes the changes needed in config.php, but there is no indication of how this is ever used since there is no other PHP involved, and it says
It is no longer possible to enable CKFinder on a page from the PHP level
All that is shown is how to create the JS snippet, which does not contain any config, and so will use incorrect settings. There is no indication of how the config properties set in config.php ever get to the JS code - as far as I can see there is no connection at all and no mention of any other PHP files, even though some are provided but not documented.
This makes no sense - PHP can quite happily generate HTML and JS that is run on the page, which is all the old CreateHTML function did. I don't understand why there is no mention of this mechanism since it was how we were supposed to use CKFinder previously - it's as if the migration guide is for some unrelated package!
If I update the config file and use the default JS widget code as suggested, it breaks the page completely, altering the MIME output type so it does not get rendered as HTML and appends this error:
{"error":{"number":10,"message":"Invalid command."}}
The docs cover various fine details of what PHP config settings mean, but nowhere that I've found says how it's ever loaded, triggered or associated with the JS. How is this supposed to work?
Indeed the CKFinder 3 documentation was lacking some important information. We're gradually adding new articles there. Based on topics you mentioned I just added:
Explanation how PHP code that worked for CKFinder 2 can be refactored to plain JavaScript in CKFinder 3. Should look familiar ;)
A table with Configuration Options Migration - JavaScript Settings which should help you with discovering again options like rememberLastFolder

Is it possible to dynamically reload PHP code while script is running?

I'm having a multiplayer server that's using PHPSockets, and thus is written entirely in PHP.
Currently, whenever I'm making any changes to the PHP server-script I have to kill the script and then start it over again. This means that any users online is disconnected (normally not a problem because there aren't so many at the moment).
Now I am rewriting the server-script to use custom PHP classes and sorten things up a little bit (you don't want to know how nasty it looks today). Today I was thinking: "Shouldn't it be possible to make changes to the php source without having to restart the whole script?".
For example, I'm planning on having a main.php file that is including user.php which contains the class MyUser and game.php which contains the class MyGame. Now let's say that I would like to make a change to user.php and "reload" the server so that the changes to user.php goes into effect, without disconnecting any online users?
I tried to find other questions that answered this, the closest I got is this question: Modifying a running script and having it reload without killing it (php) , which however doesn't seem to solve the disconnection of online users.
UPDATE
My own solutions to this were:
At special occations, include the file external.php, which can access a few variables and use them however it'd like. When doing this, I had to make sure that there were no errors in the code as the whole server would crash if I tried accessing a method that did not exist.
Rewrite the whole thing to Java, which gave me the possibility of adding a plugin system using dynamic class reloading. Works like a charm. Bye bye PHP.
Shouldn't it be possible to make changes to the php source without having to restart the whole script?
[...]
I'm planning on having a main.php file that is including user.php
which contains the class MyUser
In your case, you can't. Classes can only be defined once within a running script. You would need to restart the script to have those classes redefined.
I am not too familiar with PHP but I would assume that a process is created to run the script, in doing so it copies the instructions needed to run the program and begins execution on the CPU, during this, if you were to "update" the instructions, you'd need to kill the process ultimate and restart it. Includes are a fancy way of linking your classes and files together but ultimately the processor will have that information separate from where the file of them are stored and it is ultimately different until you restart the process.
I do not know of any system in which you can create code and actively edit it and see the changes while that code is being run. Most active programs require restart to reload new source code.
Runkit will allow you to add, remove, and redefine methods (among other things) at runtime. While you cannot change the defined properties of a class or its existing instances, it would allow you to change the behavior of those objects.
I don't recommend this as a permanent solution, but it might be useful during development. Eventually you'll want to store the game state to files, a database, Memcache, etc.
How about storing your User object into APC cache while your main script loads from the cache and checks every so often for new opcode.
To include a function in the cache, you must include the SuperClosure Class. An example would be:
if (!apc_exists('area')) {
// simple closure
// calculates area given length and width
$area = new SuperClosure(
function($length, $width) {
return $length * $width;
}
);
apc_store('area', $area);
echo 'Added closure to cache.';
} else {
$func = apc_fetch('area');
echo 'Retrieved closure from cache. ';
echo 'The area of a 6x5 polygon is: ' . $func(6,5);
}
See here for a tutorial on APC.
Simple solution use $MyUser instead of MyUser
require MyUserV1.php;
$MyUser = 'MyUserV1';
$oldUser = new $MyUser('your name');
//Some time after
require MyUserV2.php;
$MyUser = 'MyUserV2';
$newUser = new $MyUser('your name');
Every declared class stay in memory but become unused when the last MyUserV1 logout
you can make them inherit from an abstract class MyUser for using is_a
You cannot include again a file with the same class, but you can do so with an array. You can also convert from array to class, if you really need to do so. This only applies to data, though, not to behavior (methods).
I don't know much about these things with the games on PC but you can try to get all the variables from your database for the user and then update the text fields or buttons using those variables
In web is using AJAX (change data without refreshing the page).Isn't one for programming?

Changing dependency paths when deploying to different directory structure than developing in

What are some popular ways (and their caveats) of handling dependency path changes in scripted languages that will need to occur when deploying to a different directory structure?
Let the build tool do a textual replace? (such as an Ant replace?)
Say for example the src path in a HTML tag would need to change, maybe also a AJAX path in a javascript file and an include in a PHP file.
Update
I've pretty much sorted out what I need.
The only problem left is the URL that gets posted to via AJAX. At the moment this URL is in a JS config file amongst many other parameters. It is however the only parameter that changes between development, QA and production.
Unfortunately dynamically generated URLs as #prodigitalson suggested aren't desirable here--I have to support multiple server side technologies and it would get messy.
At the moment I'm leaning towards putting the URL parameter into its own JS file, deploying a different version of it for each of development, QA and production, additionally concatenating to the main config file when deployed.
IMO if you need to do this then youe developed in the wrong way. All of this shoul dbe managed in configuration file(s). On th ephp side you should have some kin dof helper that ouputs the path based on the config value... for example:
<?php echo image_tag('myimage.jpg', array('alt'=>'My Image')); ?>
<?php echo echo javascript_include('myscript.js'); ?>
In both these cases the function would look up the path to the javascript and image directories based on deployment.
For links you should be bale to generate a link based on the local install of the application and a set of parameters like:
<?php echo link_to('/user/profile', array('user_id' => 7)); // output a tag ?>
<?php echo url('/user/profile', array('user_id'=>7)); // jsut get the url ?>
As far as javascript goes you shouldnt have any paths hardcoded in a js file that need to be changed. You should make your ajax or things that are path dependent accept parameters and then you send these parameters from the view where you have the ability to use the same scripted configuration.. so oyu might have something like:
<script type="text/javascript">
siteNamespace.callAjax(
'<?php echo url('/user/profile/like', array('user_id' => 7)); ?>',
{'other': 'option'}
);
</script>
This way you can change all this in a central location based on any number of variables. Most MVC frameworks are going to do something like this though the code will look a bit different and the configuration options will vary.
I would take a look at Zend Framework MVC - specifcally the Config, Router, and View Helpers, or Symfony 1.4 and its Config, Routing and Asset and Url Helpers for example implementations.

node_delete not working

I am trying to delete some CCK nodes in Drupal using a standalone PHP script while logged in as anonymous user
if(empty($total_deals_for_this_pl)){
$node_nid = $single_result['nid'];
global $user;
$original_user = $user;
$user = user_load(1);
print $node_nid."<br>";
node_delete($node_nid);
$user = $original_user;
}
I am able to retrieve all the nid's successfully but the nodes are not getting deleted. I am loading Drupal as follows
chdir('C:\wamp\www\mysite\platform'); //my drupal resides here
require_once './includes/bootstrap.inc';
include_once './includes/common.inc';
Node_delete() has an access check for delete permissions inside it.
Test again with anonymous users given permission to delete nodes.
Also try adding
drupal_bootstrap(DRUPAL_BOOTSTRAP_DATABASE);
If that doesn't work you could try up to the session phase:
drupal_bootstrap(DRUPAL_BOOTSTRAP_SESSION);
and finally the full dealio:
drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);
Three options:
Generally, I would recommend using VBO for this kind of thing. Its a more robust solution than a custom script. It's pretty easy to set up and once you've used it you'll probably think of a dozen other ways to use it.
Failing that, make your own module and stick your custom script inside a proper hook. Your custom script on its own might not be playing along with what other modules are expecting.
If you still want to have your own separate script I suspect it's the bootstrap code that's failing. Check out drupal_bootstrap for the options available to you.

PHP File Navigation (Local + Remote)

I have been working on a content management system (nakid) and one of my toughest challenges is the file navigation. I want to make sure the file paths and settings work on local and remote servers. Right now my setup is pretty much something like this:
first.php (used by all pages):
//Set paths to nakid root
$core['dir_cur'] = dirname(__FILE__);
$core['dir_root'] = $_SERVER['DOCUMENT_ROOT'];
//Detect current nakid directory
$get_dirnakid_1 = str_replace("\\","/",dirname(__FILE__));//If on local
$get_dirnakid_2 = str_replace("/includes/php","",$get_dirnakid_1);
$get_dirnakid_3 = str_replace($_SERVER['DOCUMENT_ROOT'],"",$get_dirnakid_2);
//remove first "/"
if(substr($get_dirnakid_3, 0,1) == "/"){
$get_dirnakid_3 = substr($get_dirnakid_3, 1);
}
//Set some default vars
$core['dir_nakid_path'] = $get_dirnakid_3;
$core['dir_nakid'] = $core['dir_root']."/".$core['dir_nakid_path'];//We need to get system() for this real value - below
The reason I also did it this way is because I want the directory that this program is sitting in to be anywhere on the server ie(/nakid)(/cms)(/admin/cms)
I'm positive I am doing something the wrong way or that there is a simpler way to take care of all this.
If it helps to get a closer look at the code and how everything is being used I have it all up at nakid.org
EDIT: Just realized what I have at nakid.org is a little different than my newly posted code, but the same idea still applies to what I am attempting to do.
By and large, it looks okay to me.
You might want to give the variables more speaking names (e.g. nakid_root_dir, nakid_relative_webroot and so on.)
Remember when converting \ to / in path names: Whenever you match another directory name to one of those settings, you need to str_replace("\\","/"...) in those too.
I don't understand what you aim at with $get_dirnakid_2, though. Why will you screw up my path if I install your application in a directory that happens to be named /etc/includes/php/nakid?
Anyway, you should make those settings user overwritable as well. Sometimes, the user may want to set different settings from what you get from DOCUMENT_ROOT and consorts.
I don't fully understand what you try to get, but maybe getcwd() is what you look for:
http://www.php.net/manual/en/function.getcwd.php

Categories