Closed danyj closed 9 years ago
Id rather use JSON but according to this way of doing things it needs to be serialized
jQuery.ajax.data accepts 2 formats:
String, url-like
simple_var=val&array_1[]=val&array_1[]=val_2&array_2[x]=val&array_2[y]=val_2
This has the same structure like form values sent in POST on submit.
Object, JSON
{
simple_var: 'val',
array_1: ['val', 'val_2'],
array_2: {
x: 'val',
y: 'val_2'
}
}
Important! In this case the keys order is not guaranteed, so if in your form the value order is critical, then better to not use this solution.
For e.g. addable-...
in form names has
whatever[1][hello]=Test
whatever[2][hello]=Best
when you change the order of boxes/options (when sortable is enabled for addable-...
) then it will be
whatever[2][hello]=Test
whatever[1][hello]=Best
but when transformed to JSON, it may cause keys auto-sort and it will become
{
whatever: {
1: {
hello: 'Best'
},
2: {
hello: 'Test'
}
}
}
can I use just max 2 ajax calls ?
What stops you from doing that?
ok , thnx for the info about JSON,
but
What stops you from doing that?
well seems like I must run this in the way I described above
First ajax is to get the default array structure so that it can be compared to the option value Second one is to get my serialized options that are saved in a file
third is to get options from values required for render https://github.com/ThemeFuse/Unyson-Framework/blob/master/core/components/backend.php#L659-L666
fourth is to render
https://github.com/ThemeFuse/Unyson-Framework/blob/master/core/components/backend.php#L578-L585
or am I missing the point here in those actions ?
so basically question is can I use my saved serialized directly with render
https://github.com/ThemeFuse/Unyson-Framework/blob/master/core/components/backend.php#L578-L585
and skip the other 2 and If so how ?
to make it very short , the whole point of all this is to render my saved preset , no matter what format I have saved , JSON , serialized data , I need to render this properly the shortest way possible.
First ajax is to get the default array structure so that it can be compared to the option value Second one is to get my serialized options that are saved in a file
Why you can't put that data in html on render?
third is to get options from values required for render
Maybe this step also can be done on render? Or all the above steps in one ajax?
and If so how ?
on render put all those in data-...="..."
attributes?
Sorry, now I am focused on Backup and I am asking this by fast looking. I am feeling that I don't have enough "brain RAM" too keep track of all the details that you are trying to explain (looks complicated, or maybe because we are chatting/writing, not talking)
lol >"brain RAM" nice one
it looks complicated I admit but it is simple concept.
Why you can't put that data in html on render?
because render requires 2 things , default options JSON string and object with
ID:value
and serialize comes as
NAME:value
how would you do this
2 . how would you render that saved data
on render put all those in
data-...="..."
attributes?
Or to prevent making the html too big. On _enqueue_static()
to wp_localize_script()
the data you need.
on render put all those in data-...="..." attributes?
I had it originally like that , but it does get big , and if you have lets say 5 or more presets it gets to much for html
Simple concept being , save preset in to a file , on button click render preset
save preset in to a file
in wp-content/uploads
? because in other directory you will need FTP details from user (a form should be displayed)
how would you save data?
In DB.
how would you render that saved data?
- On option static enqueue, localize the data in javascript
- On preset save, in ajax response send the new data and update the javascript value (so it will be used on next render, instead of doing an ajax on next render to get the data)
because in other directory you will need FTP details
no way , please dont tell me this , in order to save anything to a file in let say
themes/themename/presets
I need FTP credentials?
I need presets in files so that they can be transferable from theme to theme
ok just tested on live server , saving presets to a file works ok , unless you know something that will mess this up
On regular/default server installations php can't write anywhere (because all files are owned by your_user
and php scripts are executed by www-data
user), it can write only in directories with write permissions for all 777
. wp-content/uploads
is required to be 777
because WordPress will not be able to upload images (asking FTP details on every image upload is too much).
This is the reason why WP_Filesystem
exists.
I know a person, his site was regularly hacked, then he set 755
on wp-content/uploads
, so no bad plugin or any php script can create or modify files. Only when he wants to upload some images, he sets 777
on wp-content/uploads
then sets back 755
.
I know that on most of hosting providers, there are scripts that automatically install WP and set the owner for all files to www-data
, this is convenient but not secure.
On my localhost I install apache + php manually and from php I can't change/create files. If I will set the owner to www-data
for everything, I will not be able to edit the files from IDE. The only way is to set 777
but, when I will create a new file from IDE it will be owned by current user, and it will be a mess with files owned by different users and different permissions (also permission denied errors on extensions or WordPress update). I always install an ftp server so I can enter current user and password in WP FTP details form, and PHP will connect to FTP and create/edit files as that user.
On your localhost you have MAMP executed as super-user?
I am on WAMP local and have no permission issue , just tested this concept on live cPanel apache + litespeed where by default max folder permission is 755 and it works.
http://prntscr.com/8obaqk http://prntscr.com/8obath
I have been doing same concept on Joomla since about 5 years now , and customers had no issues with files modification/creation via php . Sure proper POST checks are required and I do use
WP_Filesystem
in this case. Just hope that in WP is not much different than Joomla when it comes to folder permission issues.
This is on my localhost
Can you show the column Owner in that table?
I am on WAMP
In Windows there is not such thing multiple users, so you will never have an issue with permission denied because the file owner is another user.
On Linux can be many users (and groups), each can set permissions to files they own.
in cPanel I dont know how to show the owner column but I am sure that in this case is the user ,
I mean this relies on user permission for the folder and as long as read and write are set for the user on server it should work. I mean it did work for me for 5 years now. 100K members and few cases where their theme folder was blocked due to wrong things , but if they cant see the theme css file or run theme index.php than there is a problem , as long as those 2 work the creation /modification of files via ajax should be ok.
You really got me thinking now
To confirm what I said https://codex.wordpress.org/Changing_File_Permissions
OK , please tell me how to test bad case scenario in WP. I am on live server, what should I do , create some admin user and change permissions or ?
Find the owner of directories within wp-content/uploads/
Somehow, make sure the the owner of your theme directories (and files) is another user. For e.g. try to connect with your FTP user (if it's another user) and upload your theme via FTP (instead of WP admin upload form), so the files will be created as FTP user.
ah , ok , on it
no issue bud , created ftp user , loged in , FTP complete theme folder , ( not zip /unzip ) , activated theme and no issues. Could be my server setup that files are always owned by the user.
Which is owner of themes/themename/presets
directory and the files in it? Why php was able to create files inside the presets
directory?
I cant see it bud , I think I setup cPanel trough WHM for all files in user accounts to be owned by that user , so if you ftp anything by any user , let say cPanel owned by user1 , all files inside are owned by user1 ,
I have no environment to check this except MAMP on macbook PRO ,
if you know how I should set this up on MAMP it would be great .
On the other hand it is strange to me that WP can run n this way , 1 WP install multiple file owners
FileZilla has the Owner column
ok give me min
same owner for everything in that wp folder , i think this is lightspeed thing
Here is why it is doing it ,
WP_Filesystem
http://ottopress.com/2011/tutorial-using-the-wp_filesystem/
The WP_Filesystem basically support five different ways of writing files to the system and they all ensure that ownership of those files remains firmly in the hands of the same person that owns the WordPress files. In other words, it writes files using your user account and not as the webserver user.
and that is exactly what I used , I did not use
fopen()
or
fwrite()
directly , but used the wp file system instead
I know that. But in your case it is able to do that without FTP details (I don't know why), in my case it can't and it asks FTP details.
in my case it can't and it asks FTP details
strange , I would really like to test this in some way
so you are saying that if you do an ajax action that does
WP_Filesystem::put_contents(file_path,content);
you are asked for FTP credentials ?
I dug this up from Otto's comments
If you are on shared hosting, and see WordPress ask for FTP credentials, then it’s not running setuid methods, and it’s asking for FTP credentials as a form of protection, because it does not want to write files and have them owned by the webserver user.
WP_Filesystem::put_contents(...);
will fail.
First we make sure we have filesystem access/connection then we do actions on files.
yes I do that to , checing the wp_filesystem
/**
* Return wp_filesystem, initiate if not there
*/
public static function thz_preset_file_system(){
global $wp_filesystem;
if (empty($wp_filesystem)) {
require_once (ABSPATH . '/wp-admin/includes/file.php');
WP_Filesystem();
}
return $wp_filesystem;
}
but this is a big thing and I need to do it right
I added this code in {theme}/functions.php
add_action('admin_head', function(){
fw_print(
get_filesystem_method()
);
});
and it shows 'ftpext'
.
What it shows on your server?
in wamp and live cPanel
'direct'
I just forced the config via
define('FS_METHOD', 'ftpext');
and see what you mean. This is bad news, can you do me a favor and test on your end with this in config
define('FS_METHOD', 'ftpext');
define('FTP_BASE', 'PATH_TO_YOUR_BASE');
define('FTP_USER', 'username');
define('FTP_PASS', 'password');
define('FTP_HOST', 'host');
define('FTP_SSL', false);
and see if your ajax would now ask you for credentials
I'll try later. Recently I reinstalled my OS and I don't have configured the FTP server.
for time being until we find suitable solution I did this http://prntscr.com/8oe6y7 when you get to it please do let me know about ajax + FTP user info in config. If that works we might be ok
Your WordPress installation -> Current Theme :)
lol :) no man is WP fault , don't you know that :)
I think best fallback is to check if we can save /load to file and if not save in DB
Now lets say I cant use a file and must go to DB , can I do a blank , none existing file option save vi ajax like
fw_set_db_settings_option('menu_presets, ''{presetname:"presetdata....."")
and keep on adding to it ? ( this is the tricky one )
It will be wiped on next Theme Settings save.
I recommend to use a separate wp option, because presets data can grow and to prevent mysql error when update sql is too big.
update_option(
'thz-presets:'. fw()->theme->manifest->get_id(),
$presets,
false // https://codex.wordpress.org/Function_Reference/update_option#Parameters
);
was just busting on it , thnx much
OK how is this,
on theme install run this for example
$thz_options_presets_option = 'thz_options_presets:'. fw()->theme->manifest->get_id();
add_option($thz_options_presets_option,array(
'topmenupreset' => array(
'style1' => array(
'label' => 'Style 1',
'canremove'=> false,
'data' => '{style1data}'
),
'style2'=> array(
'label' => 'Style 2',
'canremove'=> false,
'data' => '{style2data}'
),
),
'iconboxespreset' => array(
'style1' => array(
'label' => 'Style 1',
'canremove'=> false,
'data' => '{style1data}',
),
'style2' => array(
'label' => 'Style 2',
'canremove'=> false,
'data' => '{style2data}'
),
'stylebyuser' => array(
'label' => 'User custom style',
'canremove'=> true,
'data' => '{stylebyuserdata}'
),
)
));
than use those to populate defaults , on create/update/delete new preset add/remove to that option , you think this can fly ?
I think this is hand in replacement for files option and we still have presets , I can add hidden admin option to update the file with new presets, if permissions are right , otherwise tell admin to do direct update if he/she wants more default presets
$presets = array_merge(
load_predefined_presets_from_theme_file(),
$user_presets_from_db
);
?
they will all endup in DB option , no reason to merge , on user preset save il do update_option combined with
fw_akg()
to add to it
you see i forgot about one big thing and that is theme updates , so looks like I must stay away from files creation/edits and use DB instead , since everything is deleted on theme update and I dont want to create folder outside , check permissions and all the funny stuff.
here better picture of what I mean ,
on fw_init , I do this
so now by default we have 2 predefined styles for the menu , user has option to save new preset , when he does that , I just update DB option
thz_options_presets:'. fw()->theme->manifest->get_id()
makes sense?
OK this is becoming ridiculous and I refuse to believe that this is the way this should be done.
Please help me out here.
I have in theme/options file topmenu.php that contains $options array of 20 options for top menu.
Than I have topmenu current options serialized and saved to a file , just an example
Id rather use JSON but according to this way of doing things it needs to be serialized https://github.com/ThemeFuse/Unyson/blob/bdc4f3ab1ed59e2c0b1ded227eb093cd1f556b4a/framework/static/js/fw.js#L933
Now in order for me to re-render my saved options , I need to :
is there any way to shorten this madness?
can I use just max 2 ajax calls ?