Why by every refreshing page, cache reload anew? - yii2

I've programmed my website by Yii2. When I refresh my website it works like Ctl + F5, and all the font awesome and all the cache of my site reload again. It look likes I open the page first time.
Link of my website

Add, this in your config file. According to your need.
$linkAssets
Whether to use symbolic link to publish asset files. Defaults to
false, meaning asset files are copied to $basePath. Using symbolic
links has the benefit that the published assets will always be
consistent with the source assets and there is no copy operation
required. This is especially useful during development.
'components' => [
'assetManager' => [
'linkAssets' => true,
],
]
Or
$forceCopy
Whether the directory being published should be copied even if it is
found in the target directory. This option is used only when
publishing a directory. You may want to set this to be true during the
development stage to make sure the published directory is always
up-to-date. Do not set this to true on production servers as it will
significantly degrade the performance.
'components' => [
'assetManager' => [
'forceCopy' => true,
],
]
For more info, Please click these useful links
Link Assets - Yii2 Asset Manager
Force Copy - Yii2 Asset Manager
Assets-Clear-Cache - Yii2 (Stack Overflow)
Or,
As, I am using Yii2-App-Basic. So, My Assets are getting created in ROOT/web/assets folder. So, I manually hit this action to clear my cache. This is not a good way to clear cache. Even though, it's useful for time being.
This function, I created in SiteController.php.
And, I hit URL Like : MyWebsite.com/site/clear-cache.
<?
public function actionClearCache(){
$cacheDirPath = $_SERVER['DOCUMENT_ROOT'].'/assets';
if($this->destroy_dir($cacheDirPath, 0)){
Yii::$app->session->setFlash('success', 'Cache cleared.');
}
return $this->render('some-page');
}
private function destroy_dir($dir, $i = 1) {
if (!is_dir($dir) || is_link($dir))
return unlink($dir);
foreach (scandir($dir) as $file) {
if ($file == '.' || $file == '..') continue;
if (!$this->destroy_dir($dir . DIRECTORY_SEPARATOR . $file)) {
chmod($dir . DIRECTORY_SEPARATOR . $file, 0777);
if (!$this->destroy_dir($dir . DIRECTORY_SEPARATOR . $file))
return false;
};
}
if($i == 1)return rmdir($dir);
return true;
}

Related

How can I embed external content in a WordPress widget?

I want to display a download link inside a WordPress widget. The file to be downloaded is located in the download subfolder of the site root, so that it can be uploaded via FTP. The name of the file and the text to be displayed for the download link shall be stored in a simple text file in the same folder.
Assuming WordPress is installed on www.mysite.com. The file name is setup_1_0.zip and the link display is Setup 1.0.
I am open to the file format how this information is stored as long as I can upload that file via FTP, too.
How can I embed this information inside a Custom HTML widget to get a valid download link with the text taken from that file?
How to automate the process of uploading latest software's build and download link creation in WordPress?
Based on your logic.
You are trying to automate the download process of your latest software version.
You don't want to update things manually and you just want to upload your latest build in the /download/ folder. (Only drop your latest version using FTP; that's all)
This is how I would do it:
Referencing those questions:
Get the latest file addition in a directory
How to force file download with PHP
I propose two solutions: First two separte codes, Second One inline code.
Just for educational purpose
First solution: Quick and short usage:
(You might need a way or a plugin to activate running PHP in Widget; this plugin helps PHP Code Widget)
<?php
$path = "download/";
$latest_ctime = 0;
$latest_filename = '';
$d = dir($path);
while (false !== ($entry = $d->read())) {
$filepath = "{$path}/{$entry}";
// could do also other checks than just checking whether the entry is a file
if (is_file($filepath) && filectime($filepath) > $latest_ctime) {
$latest_ctime = filectime($filepath);
$latest_filename = $entry;
}
}
echo 'Download '. $latest_filename . '';
?>
Second solution:
(Again, you might need a way or a plugin to activate running PHP in Widget; this plugin helps PHP Code Widget)
A) Create download.php in http://www.example.com/download.php
Add the following code:
<?php
$path = "download";
$latest_ctime = 0; //ctime stands for creation time.
$latest_filename = '';
$d = dir($path);
while (false !== ($entry = $d->read())) {
$filepath = "{$path}/{$entry}";
// could do also other checks than just checking whether the entry is a file
if (is_file($filepath) && filectime($filepath) > $latest_ctime) {
$latest_ctime = filectime($filepath);
$latest_filename = $entry;
}
}
// echo $latest_filename; un-comment to debug
$file_url = 'http://www.example.com/download/'.$latest_filename;
header('Content-Type: application/octet-stream');
header("Content-Transfer-Encoding: Binary");
header("Content-disposition: attachment; filename=\"" . basename($file_url) . "\"");
readfile($file_url); // do the double-download-dance (dirty but worky)
?>
B) in your WordPress HTML Widget add the following code
<?php
$path = "download";
$latest_ctime = 0;
$latest_filename = '';
$d = dir($path);
while (false !== ($entry = $d->read())) {
$filepath = "{$path}/{$entry}";
// could do also other checks than just checking whether the entry is a file
if (is_file($filepath) && filectime($filepath) > $latest_ctime) {
$latest_ctime = filectime($filepath);
$latest_filename = $entry;
}
}
echo 'Download '. $latest_filename . '';
?>
Further explanation:
A) is responsiple for downloading the latest software build automatically.
B) is responsiple for displaying Latest build name and Creating the link.
Now, You only need to upload one file to your /download/ folder which is your latest build (setup_1_0.zip, setup_1_1.zip, setup_1_2.zip ...etc. The proposed solution will check creation date regardless of file's name.)
Important note: You can see that the latest file checker function is repeated twice; once in download.php and once in WordPress Widget. Because if we combine in one file we will get header already sent error.
Dose this answer your question please? Kindly feedback.

Yii2 Noam Image manager save outside web folder

I use noam image manager for my yii2 app
https://github.com/noam148/yii2-image-manager
and in the components , they told me to put this
'components' => [
'imagemanager' => [
'class' => 'noam148\imagemanager\components\ImageManagerGetPath',
//set media path (outside the web folder is possible)
'mediaPath' => '/path/where/to/store/images/media/imagemanager',
//path relative web folder to store the cache images
'cachePath' => 'assets/images',
//use filename (seo friendly) for resized images else use a hash
'useFilename' => true,
//show full url (for example in case of a API)
'absoluteUrl' => false,
],
],
and i tried so many times to make the extension create folder outside the web folder , and always not working , can somebody help me on this ?
i found the way to move the target , all you have to do is make link shortcut in config files, and use it in params file , and also you can modified the model in the composer files directly

Including ACF (Advanced custom fields) in a custom theme or plugin: Exporting fields on distribution

I am working on a custom theme and have included acf pro inside that theme as mentioned in the docs. The theme is working fine and acf is activated on theme activation. Here is the code.
// customize ACF path
add_filter('acf/settings/path', 'my_acf_settings_path');
function my_acf_settings_path( $path ) {
$path = get_stylesheet_directory() . '/inc/advanced-custom-fields-pro/';
return $path;
}
// customize ACF dir
add_filter('acf/settings/dir', 'my_acf_settings_dir');
function my_acf_settings_dir( $dir ) {
$dir = get_stylesheet_directory_uri() . '/inc/advanced-custom-fields-pro/';
return $dir;
}
// Include ACF
include_once( get_stylesheet_directory() . '/inc/advanced-custom-fields-pro/acf.php' );
The issue i am facing for couple of hours now is due to the groups/fields that i want to be instantiated inside acf. I have some field groups that i want to be shown on fresh installation. Below are the methods i have tried:
Method 1:
I have exported the fields as json inside a folder called acf-json. ACF does recognize it and shows as a sync field. But when i try syncing it, it just creates a new empty field.
Method 2:
I have also tried exporting the field groups as php files and then including it in my functions.php file but acf doesn't recognize this code.
Distributing ACF in a theme or plugin is a bit tricky because of lack of information in the docs. The tricky part is exporting your fields with your theme and plugin, in a way that your users dont have to do anything different then what they are used to with any other theme or plugin. I will go through the procedure in detail.
For theme and plugin Development:
Referring the official docs, it should be pretty easy to copy and paste the code in your functions.php file for theme development, while for plugin development you can add it to the main plugin file. This will accomplish these 4 tasks.
Add ACF Path
Add ACF Dir
Hide ACF from clients (if needed)
Include ACF
Up till now what you have done actually doesn't do anything special. It just activates ACF whenever you activate your theme/plugin and similarly deactivates ACF on theme/plugin deactivation.
Exporting Fields: (via JSON sync)
At this stage if you distribute your theme/plugin it will just activate ACF, but it wont have any fields inside it. ACF uses JSON to keep track of all the fields and field groups. By default ACF will look for a folder called acf-json in the root of your theme. If you have this folder then ACF will automatically add/update a new json file for each field group you add or update.
You can change the location of this folder, if you want to keep it inside your includes folder. Somehow you cant change the default location on a theme, but for plugins you can by adding this code.
add_filter('acf/settings/save_json', 'set_acf_json_save_folder');
function set_acf_json_save_folder( $path ) {
$path = dirname(__FILE__) . '/includes/acf-json';
return $path;
}
add_filter('acf/settings/load_json', 'add_acf_json_load_folder');
function add_acf_json_load_folder( $paths ) {
unset($paths[0]);
$paths[] = dirname(__FILE__) . '/includes/acf-json';
return $paths;
}
Now if you share this theme/plugin with someone, when they go inside ACF they should see a new option for sync. On syncing all the files fields should be available to them.
Automatting the SYNC Process:
If you want to hide ACF completely then obviously you cant have your users go inside ACF and sync fields. So in this case you need a script that would automatically sync all the fields from the json folder. You can add this code inside your functions.php for themes or inside your main plugin file. You dont have to change any paths in this script because in the previous code you have already told ACF where to load the JSON files from.
add_action( 'admin_init', 'article_gamification_sync_acf_fields' );
function article_gamification_sync_acf_fields() {
// vars
$groups = acf_get_field_groups();
$sync = array();
// bail early if no field groups
if( empty( $groups ) )
return;
// find JSON field groups which have not yet been imported
foreach( $groups as $group ) {
// vars
$local = acf_maybe_get( $group, 'local', false );
$modified = acf_maybe_get( $group, 'modified', 0 );
$private = acf_maybe_get( $group, 'private', false );
// ignore DB / PHP / private field groups
if( $local !== 'json' || $private ) {
// do nothing
} elseif( ! $group[ 'ID' ] ) {
$sync[ $group[ 'key' ] ] = $group;
} elseif( $modified && $modified > get_post_modified_time( 'U', true, $group[ 'ID' ], true ) ) {
$sync[ $group[ 'key' ] ] = $group;
}
}
// bail if no sync needed
if( empty( $sync ) )
return;
if( ! empty( $sync ) ) { //if( ! empty( $keys ) ) {
// vars
$new_ids = array();
foreach( $sync as $key => $v ) { //foreach( $keys as $key ) {
// append fields
if( acf_have_local_fields( $key ) ) {
$sync[ $key ][ 'fields' ] = acf_get_local_fields( $key );
}
// import
$field_group = acf_import_field_group( $sync[ $key ] );
}
}
}
**Now when you distribute your theme/plugin, on activation it will also activate ACF, then copy all the json files and execute them. This will automatically sync all the field groups, now you can even hide your ACF plugin, and none of your users ever have to go inside ACF to sync fields, infact they wont even have to know that ACF exists on their site. Secondly even if you make a new change in ACF, it should automatically update changes to the json files. You can now even version control them for better control. **

Why is code loading before doctype

<?php
# Alert the user that this is not a valid access point to MediaWiki if they try to access the special pages file directly.
if ( !defined( 'MEDIAWIKI' ) ) {
echo <<<EOT
To install my extension, put the following line in LocalSettings.php:
require_once "$IP/extensions/Userprofile/Userprofile.php";
EOT;
exit( 1 );
}
$wgExtensionCredits['specialpage'][] = array(
'path' => __FILE__,
'name' => 'Userprofile',
'author' => 'matsuiny2004',
'url' => 'http://localhost/mywiki/index.php/Extension:Userprofile',
'descriptionmsg' => 'userprofile-desc',
'version' => '0.0.0',
);
$wgAutoloadClasses['SpecialUserprofile'] = __DIR__ . '/SpecialUserprofile.php'; # Location of the SpecialMyExtension class (Tell MediaWiki to load this file)
$wgMessagesDirs['Userprofile'] = __DIR__ . "/i18n"; # Location of localisation files (Tell MediaWiki to load them)
$wgExtensionMessagesFiles['UserprofileAlias'] = __DIR__ . '/Userprofile.alias.php'; # Location of an aliases file (Tell MediaWiki to load it)
$wgSpecialPages['Userprofile'] = 'SpecialUserprofile'; # Tell MediaWiki about the new special page and its class name
function extensionFunction() {
# Assume $title is the title object
if( $title->isProtected( 'edit' ) ) {
# Protected from editing, do things
} else {
# Not protected from editing
}
}
//test code here
echo '<div id="navigation">Navigation</div>';
?>
<?php
echo '<div id="account">account</div>';
?>
<?php
echo '<div id="editpage">edit page</div>';
?>
<div id='border-search'>
<img src="http://s6.postimage.org/z6ixulv6l/searchbox_border.png"></img>
</div>
?php>
<div class='rectangle-box'>
<div class='rectangle-content'></div>
</div>
I am including extra php and html code from a seperate file that I load as an extension in mediawiki to create a custom layout. the problem is that the code loads before the doctype making the page render in quirks mode in IE and safari. How can i get it to load after the doctype tag?
The problem is that you have top-level echo statements all over your code (by top level I mean ones that are not included in any function). Which is why the PHP engine executes them as soon as it sees them, which is before the MediaWiki itself starts running.
MediaWiki has some good documentation explaining all kinds of hooks. What you should do is write a few functions and place all your echo-ing code there, and expect this function to be executed when the event in question occurs.
I see a good starter page here. Relevant example is:
$wgHooks['ArticleSave'][] = 'wgAddStub';
function wgAddStub( &$article, &$user, &$text, &$summary, $minor, $watchthis, $sectionanchor, &$flags, &$status ) {
$text = ( $article->exists() ? "" : "{{stub}}\n" ) . $text;
return true;
}

How can I use html5 cache manifest with CakePHP?

I want to use the html5 cache manifest technology with CakePHP,
but I don't know where to place the cache manifest in CakePHP,
I've searched for a solution, but I do not found anything.
Can you help me?
The best and easiest way to access one manifest file in all views is to look at your layouts, for example
View/Layouts/default.ctp
and replace <html> with
<?php echo "<html manifest='".$this->webroot."manifest.php'>"; ?>
in which manifest.php is located in
app/webroot/manifest.php
and looks something like this:
<?php
header('Content-Type: text/cache-manifest');
echo "CACHE MANIFEST\n";
echo "\n\nNETWORK:\n";
echo "*\n";
echo "\n\nCACHE:\n";
echo "# Version: 1\n";
?>
So the manifest.php is only needed once and can be used for all views.
HINT:
For a dynamic manifest-file you can use a code snippet from here:
http://nial.me/2010/01/using-the-html5-cache-manifest-with-dynamic-files/
I tried this solution, putting the manifest in default.ctp, but it causes some problems, all my pages was cached... i think it's discribed in the spec "...the page that referenced the manifest is automatically cached even if it isn't explicitly mentioned".
...couse this all my pages was being cached, manifest is checked in each page. And when another user logs in they see the last user homepage and other pages.
The final solution: create a redirect/loading page
1 - create the redirect page:
I had create the Pages/redirect.ctp file and the function redirect(){} in the Pages controller. A simple page, just with a hello message and a loading bar based on the applicationCache progress event:
var appCache = window.applicationCache;
appCache.addEventListener('progress', function(event) {
console.log(event.loaded + " of " + event.total + " files...");
//make some changes in the page' loading bar
}, false);
2 - Load manifest only in the redirect page:
In the View/Layouts/default.ctp I filtered the tag to show the manifest only in the redirect page:
<? if($this->request->params['controller']=='pages' &&
$this->request->params['action']=='redirect'): ?><html
manifest="<?=$this->webroot?>manifest.php">
<? else: ?>
<html >
<?
endif; ?>
3 - Use the redirect page in the auth component to lead my user
to redirect page after login:
In the appController a setted auth component like this
public $components = array (
'Session',
'Auth' => array (
'authError' => "user or password invalid",
'unauthorizedRedirect' => "/pages/redirect?err=login",
'loginRedirect' => "/pages/redirect",
'logoutRedirect' => "/",
'loginAction' => "/user/login",
'authorize' => array ('Controller')
)
);
now only the elements putted in the manifest will be cached. The redirect page is cached (according the spec) but the applicationCache event updates the page torning this "dinamic".
If you mean the manifest file it should go into /app/webroot, the directory that your vhost should also use for the site. besides this there is nothing really related to CakePHP with this.
Have a look at this: http://www.html5rocks.com/en/tutorials/appcache/beginner/