added inline code to plugin tools
This commit is contained in:
6
plugins/fipfcard_plugin/css/menu/menu.css
Normal file
6
plugins/fipfcard_plugin/css/menu/menu.css
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
#mytext {
|
||||||
|
border: 1px solid blue;
|
||||||
|
}
|
||||||
|
#mytext_2 {
|
||||||
|
border: 1px solid green;
|
||||||
|
}
|
||||||
@@ -10,8 +10,18 @@ if (!defined('ABSPATH')) {
|
|||||||
function fipfcard_plugin_content() {
|
function fipfcard_plugin_content() {
|
||||||
$fipfcard = new PLGNTLS_class();
|
$fipfcard = new PLGNTLS_class();
|
||||||
|
|
||||||
|
$my_css = '
|
||||||
|
#mytext {
|
||||||
|
background-color: lightblue;
|
||||||
|
}
|
||||||
|
#mytext_2 {
|
||||||
|
background-color: lightgreen;
|
||||||
|
}
|
||||||
|
';
|
||||||
echo $fipfcard->add_to_front( array(
|
echo $fipfcard->add_to_front( array(
|
||||||
array("js/menu/example_menu.js", 'type'=>'module'),
|
array("js/menu/example_menu.js", 'type'=>'module'),
|
||||||
|
"css/menu/menu.css",
|
||||||
|
"PLGNTLS_menu_css" => array('css'=>$my_css),
|
||||||
"js/menu/example_menu_2.js",
|
"js/menu/example_menu_2.js",
|
||||||
"html/menu/example_menu.html",
|
"html/menu/example_menu.html",
|
||||||
));
|
));
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
* - afficher_offre_*
|
* - afficher_offre_*
|
||||||
* - -> Masquer / *
|
* - -> Masquer / *
|
||||||
* - offre_x* (image, titre, txt)
|
* - offre_x* (image, titre, txt)
|
||||||
|
*/
|
||||||
function my_custom_js_function_PLGNTLS() {
|
function my_custom_js_function_PLGNTLS() {
|
||||||
if (!is_singular("project"))
|
if (!is_singular("project"))
|
||||||
return ;
|
return ;
|
||||||
@@ -63,7 +64,162 @@ function my_custom_js_function_PLGNTLS() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
add_action('wp_footer', 'my_custom_js_function_PLGNTLS');
|
add_action('wp_footer', 'my_custom_js_function_PLGNTLS');
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
in my_custom_df_form_handler
|
||||||
|
|
||||||
|
form_id
|
||||||
|
crea_partenaire
|
||||||
|
|
||||||
|
post_array
|
||||||
|
{
|
||||||
|
"post_status":"publish",
|
||||||
|
"field_title":
|
||||||
|
[
|
||||||
|
"Nom commercial",
|
||||||
|
"Votre site Internet",
|
||||||
|
"Dans quelle rubrique devez-vous para\u00eetre ? ",
|
||||||
|
"L\\'accroche en t\u00eate de page",
|
||||||
|
"Pr\u00e9sentez-vous",
|
||||||
|
"Votre logo ",
|
||||||
|
"Image principale",
|
||||||
|
"Titre",
|
||||||
|
"Texte de l\\'offre",
|
||||||
|
"Image (facultatif)",
|
||||||
|
"Voulez-vous ajouter une offre ?",
|
||||||
|
"Voulez-vous afficher cette offre ?",
|
||||||
|
"Titre",
|
||||||
|
"Texte de l\\'offre",
|
||||||
|
"Image (facultatif)",
|
||||||
|
"Voulez-vous ajouter une offre ?",
|
||||||
|
"Voulez-vous afficher l\\'offre ?",
|
||||||
|
"Titre",
|
||||||
|
"Texte de l\\'offre",
|
||||||
|
"Image (facultatif)"
|
||||||
|
],
|
||||||
|
"post_title":"test",
|
||||||
|
"meta_input":
|
||||||
|
[
|
||||||
|
"de_fb_url_partenaire",
|
||||||
|
"de_fb_logo_partenaire",
|
||||||
|
"de_fb_offre_1_titre",
|
||||||
|
"de_fb_offre_1_txt",
|
||||||
|
"de_fb_offre_1_image",
|
||||||
|
"de_fb_ajouter_offre_2",
|
||||||
|
"de_fb_afficher_offre_2",
|
||||||
|
"de_fb_offre_2_titre",
|
||||||
|
"de_fb_offre_2_txt",
|
||||||
|
"de_fb_offre_2_image",
|
||||||
|
"de_fb_ajouter_offre_3",
|
||||||
|
"de_fb_afficher_offre_3",
|
||||||
|
"de_fb_offre_3_titre",
|
||||||
|
"de_fb_offre_3_txt",
|
||||||
|
"de_fb_offre_3_image"
|
||||||
|
],
|
||||||
|
"url_partenaire":"",
|
||||||
|
"tax_input":["de_fb_project_category"],
|
||||||
|
"project_category":"hebergement",
|
||||||
|
"post_excerpt":"test",
|
||||||
|
"post_content":"test",
|
||||||
|
"_ajax_linking_nonce":"0e855ae1a9",
|
||||||
|
"logo_partenaire":"38157",
|
||||||
|
"post_thumbnail":"38156",
|
||||||
|
"offre_1_titre":"test",
|
||||||
|
"offre_1_txt":"test",
|
||||||
|
"offre_1_image":"",
|
||||||
|
"ajouter_offre_2":"Oui",
|
||||||
|
"afficher_offre_2":"Masquer",
|
||||||
|
"offre_2_titre":"test",
|
||||||
|
"offre_2_txt":"test",
|
||||||
|
"offre_2_image":"",
|
||||||
|
"ajouter_offre_3":"Non",
|
||||||
|
"offre_3_image":"",
|
||||||
|
"ID":"38158",
|
||||||
|
"form_type_confirm":""
|
||||||
|
}
|
||||||
|
|
||||||
|
form_type
|
||||||
|
project
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
-------------
|
||||||
|
|
||||||
|
in PLGNTLS_df_after_insert_post_handler
|
||||||
|
|
||||||
|
form_id
|
||||||
|
crea_partenaire
|
||||||
|
|
||||||
|
post_id
|
||||||
|
38158
|
||||||
|
|
||||||
|
post_array
|
||||||
|
{
|
||||||
|
"post_status":"publish",
|
||||||
|
"field_title":
|
||||||
|
[
|
||||||
|
1. "Nom commercial",
|
||||||
|
2. "Votre site Internet",
|
||||||
|
3. "Dans quelle rubrique devez-vous para\u00eetre ? ",
|
||||||
|
4. "L\\'accroche en t\u00eate de page",
|
||||||
|
5. "Pr\u00e9sentez-vous",
|
||||||
|
6. "Votre logo ",
|
||||||
|
7. "Image principale",
|
||||||
|
8. "Titre",
|
||||||
|
9. "Texte de l\\'offre",
|
||||||
|
10. "Image (facultatif)",
|
||||||
|
11. "Voulez-vous ajouter une offre ?",
|
||||||
|
12. "Voulez-vous afficher cette offre ?",
|
||||||
|
13. "Titre","Texte de l\\'offre",
|
||||||
|
14. "Image (facultatif)",
|
||||||
|
15. "Voulez-vous ajouter une offre ?",
|
||||||
|
16. "Voulez-vous afficher l\\'offre ?",
|
||||||
|
17. "Titre",
|
||||||
|
18. "Texte de l\\'offre",
|
||||||
|
19. "Image (facultatif)"
|
||||||
|
],
|
||||||
|
"post_title":"test",
|
||||||
|
"meta_input":
|
||||||
|
{
|
||||||
|
1. "url_partenaire":"",
|
||||||
|
2. "_url_partenaire":"field_65cb83096d020",
|
||||||
|
3. "logo_partenaire":"38157",
|
||||||
|
4. "_logo_partenaire":"field_65cb79150ac4f",
|
||||||
|
5. "offre_1_titre":"test",
|
||||||
|
6. "_offre_1_titre":"field_65d8bbf6b4651",
|
||||||
|
7. "offre_1_txt":"test",
|
||||||
|
8. "_offre_1_txt":"field_65d8bc395bf88",
|
||||||
|
9. "offre_1_image":"",
|
||||||
|
10. "_offre_1_image":"field_65d8bc5d5bf8b",
|
||||||
|
11. "ajouter_offre_2":"Oui",
|
||||||
|
12. "_ajouter_offre_2":"field_65d8c834e1ac9",
|
||||||
|
13. "afficher_offre_2":"Masquer",
|
||||||
|
14. "_afficher_offre_2":"field_65d8cf09395a5",
|
||||||
|
15. "offre_2_titre":"test",
|
||||||
|
16. "_offre_2_titre":"field_65d8bc201740b",
|
||||||
|
17. "offre_2_txt":"test",
|
||||||
|
18. "_offre_2_txt":"field_65d8bc4c5bf89",
|
||||||
|
19. "offre_2_image":"",
|
||||||
|
20. "_offre_2_image":"field_65d8bc6e5bf8c",
|
||||||
|
21. "ajouter_offre_3":"Non",
|
||||||
|
22. "_ajouter_offre_3":"field_65d8c880fb783",
|
||||||
|
23. "afficher_offre_3":[],
|
||||||
|
24. "offre_3_titre":[],
|
||||||
|
25. "offre_3_txt":[],
|
||||||
|
26. "offre_3_image":"",
|
||||||
|
27. "_offre_3_image":"field_65d8bc8c5bf8e"
|
||||||
|
},
|
||||||
|
"tax_input":{"project_category":[39]},
|
||||||
|
"post_excerpt":"test",
|
||||||
|
"post_content":"test",
|
||||||
|
"_ajax_linking_nonce":"0e855ae1a9",
|
||||||
|
"post_thumbnail":"38156",
|
||||||
|
"ID":"38158",
|
||||||
|
"form_type_confirm":"",
|
||||||
|
"post_type":"project",
|
||||||
|
"post_date":"2024-02-28 18:57:20"
|
||||||
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
?>
|
?>
|
||||||
|
|||||||
@@ -8,6 +8,9 @@
|
|||||||
*
|
*
|
||||||
* PLGNTLS means PLUGIN TOOLS
|
* PLGNTLS means PLUGIN TOOLS
|
||||||
*
|
*
|
||||||
|
* .add_to_front() : this method is made to add files and codes all at once
|
||||||
|
* otherwise use the wp functions (wp_enqueue_*, wp_add_inline_*, etc)
|
||||||
|
*
|
||||||
*
|
*
|
||||||
* ex:
|
* ex:
|
||||||
*
|
*
|
||||||
@@ -16,34 +19,31 @@
|
|||||||
* $var_2 = 'value_2';
|
* $var_2 = 'value_2';
|
||||||
* $var_3 = 'value_3';
|
* $var_3 = 'value_3';
|
||||||
* return $my_plugin_class->add_to_front(
|
* return $my_plugin_class->add_to_front(
|
||||||
* array(
|
* array( // files added in order by types
|
||||||
* 'path/to/style.css' // those files are added to front
|
* 'path/to/style1.css', //
|
||||||
* 'path/to/script.js' // in the order you put them
|
* 'path/to/script1.js', //
|
||||||
* 'http://my_url.com' // it can be urls
|
* 'path/to/style2.css', // -> depends on style1.css
|
||||||
* 'path/to/file.html' // html are just rendered then returned
|
* 'http://my_url1.com', //
|
||||||
|
* 'path/to/script2.js', // -> depends on script1.js
|
||||||
|
* 'path/to/file1.html', // | will be returned
|
||||||
|
* 'path/to/file2.html', // -> | as expanded html
|
||||||
|
* 'path/to/file3.html', // | in the order included
|
||||||
|
* 'handle_name' => 'path/to/script3.js', // -> depends on the script with handle 'handle_name'
|
||||||
|
* array( //
|
||||||
|
* 'path/to/script4.js', // | add a script with attributes
|
||||||
|
* 'attribute_1' => 'value_1', // -> | first element of array must be
|
||||||
|
* 'attribute_2' => 'value_2', // | the script, without explicit key
|
||||||
|
* ), //
|
||||||
|
* array( 'js' => 'var_js' ), // -> add inline js, only first element will be used
|
||||||
|
* array( 'css' => 'var_css' ), // -> add inline css, only first element will be used
|
||||||
* ),
|
* ),
|
||||||
* compact( // these variables are added to html and js files
|
* compact( // these variables are added to html and js files
|
||||||
* 'var_1', // in html files you can access them directly
|
* 'var_1', // - in html files you can access them directly
|
||||||
* 'var_2', // in js files they are properties of object PLGNTLS_data
|
* 'var_2', // - in js files they are properties of object PLGNTLS_data
|
||||||
* 'var_3', // like PLGNTLS_data.var_1;
|
* 'var_3', // like PLGNTLS_data.var_1;
|
||||||
* )
|
* )
|
||||||
* );
|
* );
|
||||||
*
|
*
|
||||||
* complete syntax to include js scripts :
|
|
||||||
*
|
|
||||||
* key => value
|
|
||||||
* 1: 'src'
|
|
||||||
* 2: 'dependence' => 'src'
|
|
||||||
* 3: array( 'src', 'attr_1' => 'value_1', ... )
|
|
||||||
* 4: 'dependence' => array( 'src', 'attr_1' => 'value_1', ... )
|
|
||||||
*
|
|
||||||
* -> 'src' is required
|
|
||||||
* -> 'dependence' is optional
|
|
||||||
* explicit key is always a dependence
|
|
||||||
* -> value can be a string 'src', or an array('srcs', ...)
|
|
||||||
* if value is array, first element is 'src' and following
|
|
||||||
* are attributes for <script> html elements
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class PLGNTLS_class
|
class PLGNTLS_class
|
||||||
@@ -52,10 +52,10 @@ class PLGNTLS_class
|
|||||||
private static $_root_url;
|
private static $_root_url;
|
||||||
|
|
||||||
private $_first_script;
|
private $_first_script;
|
||||||
|
private $_first_style;
|
||||||
private $_prefix;
|
private $_prefix;
|
||||||
private $_js_dependencies;
|
private $_js_dependencies;
|
||||||
private $_css_dependencies;
|
private $_css_dependencies;
|
||||||
private $_scripts_modules;
|
|
||||||
private $_scripts_attributes;
|
private $_scripts_attributes;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -63,9 +63,9 @@ class PLGNTLS_class
|
|||||||
public function __construct() {
|
public function __construct() {
|
||||||
$this->_prefix = "PLGNTLS";
|
$this->_prefix = "PLGNTLS";
|
||||||
$this->_first_script = null;
|
$this->_first_script = null;
|
||||||
|
$this->_first_style = null;
|
||||||
$this->_js_dependencies = array();
|
$this->_js_dependencies = array();
|
||||||
$this->_css_dependencies = array();
|
$this->_css_dependencies = array();
|
||||||
$this->_scripts_modules = array();
|
|
||||||
$this->_scripts_attributes = array();
|
$this->_scripts_attributes = array();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -95,8 +95,6 @@ class PLGNTLS_class
|
|||||||
if (!is_null($srcs_arr))
|
if (!is_null($srcs_arr))
|
||||||
$this->add_fetch($srcs_arr, $vars);
|
$this->add_fetch($srcs_arr, $vars);
|
||||||
|
|
||||||
array_push($this->_scripts_modules, 'PLGNTLS_example_menu_js', 'PLGNTLS_plgntls_fetch_js');
|
|
||||||
|
|
||||||
$srcs = array();
|
$srcs = array();
|
||||||
foreach($srcs_arr as $src_key => $src_value) {
|
foreach($srcs_arr as $src_key => $src_value) {
|
||||||
$init = $this->init_src($src_key, $src_value);
|
$init = $this->init_src($src_key, $src_value);
|
||||||
@@ -234,7 +232,13 @@ class PLGNTLS_class
|
|||||||
$previous_css_basename = '';
|
$previous_css_basename = '';
|
||||||
$previous_js_basename = '';
|
$previous_js_basename = '';
|
||||||
foreach ($srcs_arr as $src) {
|
foreach ($srcs_arr as $src) {
|
||||||
if (in_array($src->ext, array("js", "url"))) {
|
if ($src->inline !== null) {
|
||||||
|
if ($src->inline === "js")
|
||||||
|
$this->add_inline_script($src);
|
||||||
|
else if ($src->inline === "css")
|
||||||
|
$this->add_inline_style($src);
|
||||||
|
}
|
||||||
|
else if (in_array($src->ext, array("js", "url"))) {
|
||||||
$this->add_script($src, $previous_js_basename);
|
$this->add_script($src, $previous_js_basename);
|
||||||
$previous_js_basename = $src->handle;
|
$previous_js_basename = $src->handle;
|
||||||
}
|
}
|
||||||
@@ -246,13 +250,16 @@ class PLGNTLS_class
|
|||||||
|
|
||||||
// https://developer.wordpress.org/reference/hooks/wp_script_attributes/
|
// https://developer.wordpress.org/reference/hooks/wp_script_attributes/
|
||||||
// https://wordpress.stackexchange.com/questions/66843/attach-a-private-function-at-a-hook
|
// https://wordpress.stackexchange.com/questions/66843/attach-a-private-function-at-a-hook
|
||||||
add_filter( 'wp_script_attributes', fn($attr)=>$this->add_type_module($attr), 10, 1 );
|
add_filter( 'wp_script_attributes', fn($attr)=>$this->add_attributes_to_script($attr), 10, 1 );
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* uncomment to print all enqueued scripts, can be usefull
|
* uncomment to print all enqueued files, can be usefull
|
||||||
global $wp_scripts;
|
global $wp_scripts;
|
||||||
error_log("wp_scripts->queue:");
|
error_log("wp_scripts->queue:");
|
||||||
error_log(json_encode($wp_scripts->queue));
|
error_log(json_encode($wp_scripts->queue));
|
||||||
|
global $wp_styles;
|
||||||
|
error_log("wp_styles->queue:");
|
||||||
|
error_log(json_encode($wp_styles->queue));
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
private function add_script($script, $previous_js_basename) {
|
private function add_script($script, $previous_js_basename) {
|
||||||
@@ -263,14 +270,28 @@ class PLGNTLS_class
|
|||||||
wp_enqueue_script( $script->handle, $script->url, $depends_on, $script->version, true);
|
wp_enqueue_script( $script->handle, $script->url, $depends_on, $script->version, true);
|
||||||
}
|
}
|
||||||
private function add_style($style, $previous_css_basename) {
|
private function add_style($style, $previous_css_basename) {
|
||||||
|
if (is_null($this->_first_style))
|
||||||
|
$this->_first_style = $style->handle;
|
||||||
$depends_on = $this->check_dependencies($style, $previous_css_basename);
|
$depends_on = $this->check_dependencies($style, $previous_css_basename);
|
||||||
if ($depends_on !== null)
|
if ($depends_on !== null)
|
||||||
wp_enqueue_style( $style->handle, $style->url, $depends_on, $style->version, '');
|
wp_enqueue_style( $style->handle, $style->url, $depends_on, $style->version, '');
|
||||||
}
|
}
|
||||||
|
private function add_inline_script($src) {
|
||||||
|
$handle = $src->depends;
|
||||||
|
if ($handle === null)
|
||||||
|
$handle = $this->_first_script;
|
||||||
|
wp_add_inline_script($src->depends, $src->src, 'before');
|
||||||
|
}
|
||||||
|
private function add_inline_style($src) {
|
||||||
|
error_log("inside add_inline_style");
|
||||||
|
$handle = $src->depends;
|
||||||
|
if ($handle === null)
|
||||||
|
$handle = $this->_first_style;
|
||||||
|
wp_add_inline_style($src->depends, $src->src);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private function add_attributes_to_script($attr) {
|
||||||
private function add_type_module($attr) {
|
|
||||||
if (empty($attr['id']))
|
if (empty($attr['id']))
|
||||||
return $attr;
|
return $attr;
|
||||||
$handle = $attr['id'];
|
$handle = $attr['id'];
|
||||||
@@ -330,20 +351,52 @@ class PLGNTLS_class
|
|||||||
* 6. version : used to avoid browser caching
|
* 6. version : used to avoid browser caching
|
||||||
* 7. depends : string if depends on a handle, or ''
|
* 7. depends : string if depends on a handle, or ''
|
||||||
* 8. attr : associative array of html attribute like 'type'=>'module'
|
* 8. attr : associative array of html attribute like 'type'=>'module'
|
||||||
|
* 9. inline : array("js" => "name.js") -> js
|
||||||
|
* array("css" => "name.css") -> css
|
||||||
*/
|
*/
|
||||||
private function init_src($key, $value) {
|
private function init_src($key, $value) {
|
||||||
if (empty($value))
|
if (empty($value))
|
||||||
return null;
|
return null;
|
||||||
$src = (object)[];
|
$src = (object)[
|
||||||
|
'src' => null,
|
||||||
|
'ext' => null,
|
||||||
|
'basename' => null,
|
||||||
|
'handle' => null,
|
||||||
|
'url' => null,
|
||||||
|
'path' => null,
|
||||||
|
'version' => null,
|
||||||
|
'depends' => null,
|
||||||
|
'attr' => null,
|
||||||
|
'inline' => null,
|
||||||
|
];
|
||||||
|
|
||||||
|
// 7. depends
|
||||||
|
$src->depends = '';
|
||||||
|
if (is_string($key))
|
||||||
|
$src->depends = $key;
|
||||||
|
|
||||||
// 0. src
|
// 0. src
|
||||||
// 8. attr
|
// 8. attr
|
||||||
|
// 9. inline
|
||||||
|
// first element of array is used, so must not be empty
|
||||||
|
// value => ['path/to/file', 'key1'=>'value1', 'key2'=>'value2']
|
||||||
|
// src => 'path/to/file'
|
||||||
|
// attr => ['key1'=>'value1', 'key2'=>'value2']
|
||||||
if (is_array($value)){
|
if (is_array($value)){
|
||||||
$src->src = array_shift($value);
|
$first_key = array_keys($value)[0];
|
||||||
$src->attr = $value;
|
if (empty($value[$first_key]))
|
||||||
|
return null;
|
||||||
|
if ($first_key === 0) { // is a script file or url with attributes
|
||||||
|
$src->src = array_shift($value);
|
||||||
|
$src->attr = $value;
|
||||||
|
}
|
||||||
|
else if ($first_key === "js" || $first_key === "css") { // is an inline code
|
||||||
|
$src->src = $value[$first_key];
|
||||||
|
$src->inline = $first_key;
|
||||||
|
return $src; // inline only needs 'depends', 'src' and 'inline'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
$src->src = $value;
|
$src->src = $value;
|
||||||
$src->attr = null;
|
$src->attr = null;
|
||||||
}
|
}
|
||||||
@@ -384,14 +437,12 @@ class PLGNTLS_class
|
|||||||
$src->version = date("ymd-Gis", filemtime($src->path));
|
$src->version = date("ymd-Gis", filemtime($src->path));
|
||||||
}
|
}
|
||||||
|
|
||||||
// 7. depends
|
// if ext is 'js' or 'url' and attr is not empty
|
||||||
$src->depends = '';
|
|
||||||
if (is_string($key))
|
|
||||||
$src->depends = $key;
|
|
||||||
|
|
||||||
// also add to global variable to access in 'wp_script_attributes' filter
|
// also add to global variable to access in 'wp_script_attributes' filter
|
||||||
if ($src->attr !== null) {
|
if ($src->ext === 'js' || $src->ext === 'url') {
|
||||||
$this->_scripts_attributes[$src->handle.'-js'] = $src->attr;
|
if ($src->attr !== null) {
|
||||||
|
$this->_scripts_attributes[$src->handle.'-js'] = $src->attr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $src;
|
return $src;
|
||||||
|
|||||||
2
private
2
private
Submodule private updated: 5252a3d6c2...8bb03bf518
Reference in New Issue
Block a user