init($base);
self::$dsnmanager = $this;
return $this;
}
private function init($base) {
// add translation support
load_plugin_textdomain(DSNMANAGER_TEXTDOMAIN, PLUGINDIR . 'admin-dashboard-site-notes/languages', 'admin-dashboard-site-notes/languages' );
// define all of the capabilities even though at this point there's just one capability used
$this->capabilities = array(
'publish_posts' => 'publish_'.$this->post_type_name_cap,
'edit_posts' => 'edit_'.$this->post_type_name_cap,
'edit_others_posts' => 'edit_others_'.$this->post_type_name_cap,
'delete_posts' => 'delete_'.$this->post_type_name_cap,
'delete_others_posts' => 'delete_others_'.$this->post_type_name_cap,
'read_private_posts' => 'read_private_'.$this->post_type_name_cap,
'edit_post' => 'edit_'.$this->post_type_name,
'delete_post' => 'delete_'.$this->post_type_name,
'read_post' => 'read_'.$this->post_type_name,
);
// cache our options before doing anything, since everything else depends on them
$this->options = $this->get_all_options();
// check if we need to run any upgrade scripts and if so, do it
$this->handle_upgrades();
// base name should be plugin_basename(__FILE__) to check when WP is referring to this plugin, but since this is an include, we need to have it passed in by the actual file
$this->plugin_base = $base;
// create the site note content type
if(!defined('DSN_DISABLE_CHANGES')) {
$this->add_content_type();
}
// add hooks and filters
add_filter('plugin_action_links',array(&$this,'extra_plugin_links_primary'),10,2);
add_filter('plugin_row_meta',array(&$this,'extra_plugin_links_secondary'),10,2);
add_action('all_admin_notices',array(&$this,'all_admin_notices'));
add_action('admin_init',array(&$this,'admin_init'));
add_filter('dsn_sanitize_title',array(&$this,'_sanitize_title'),99);
add_filter('dsn_sanitize',array($this,'_sanitize'),99);
add_filter('dsn_author_name',array($this,'_author_name'),99,2);
if($this->options['support_author']) {
add_filter('dsn_contextual_help_content',array($this,'_append_author_name'),99,2);
add_filter('dsn_admin_notice_content',array($this,'_append_author_name'),99,2); // TODO
add_filter('dsn_widget_content',array($this,'_append_author_name'),99,2); // TODO
}
// add styles/scripts
add_action('admin_enqueue_scripts',array($this,'enqueue_includes'));
// add dashboard widget notes if there are any
if($this->has_dashboard_notes()) {
add_action('wp_dashboard_setup', array($this,'setup_dashboard'));
}
// add instruction manual page if entries exist
if($this->has_instruction_notes()) {
add_action( 'admin_menu', array($this,'admin_menu') );
}
// add the options page if this user can manage the options
if($this->user_has_admin()) {
if(!defined('DSN_DISABLE_CHANGES')) {
add_action('admin_menu', array($this,'add_config_menu'));
add_action('admin_init', array($this,'register_settings'));
}
}
// check if we can add contextual help (added in WP v3.3) and if so, add that action
$wp_version = get_bloginfo('version');
if( version_compare($wp_version, '3.3.0') >= 0) {
add_action('current_screen',array($this,'current_screen'),999);
}
}
public function get_author_name($author_id) {
// display_name cannot be trusted; a user can set it to literally any string they want that doesn't have html in it, such as someone else's name
return esc_html(sprintf(__("%s (%s)"), get_the_author_meta('display_name',$author_id), get_the_author_meta('user_login',$author_id)));
}
public function _append_author_name($content, $post) {
$author_name = esc_html(apply_filters('dsn_author_name', $this->get_author_name($post->post_author), $post->post_author));
$author_info = "
{$author_name}
";
return $content . $author_info;
}
public function _author_name($name, $id) {
return esc_html(sprintf(__("- %s"), $name));
}
private function handle_upgrades() {
global $wpdb;
$prefix = $this->custom_field_prefix;
// if there's no version set in the database, it's a pre-1.3 version, so run the "upgrade" code and then create the version
if(!isset($this->options['version']) || version_compare($this->options['version'], '1.3', '<')) {
require_once('upgrades/update-1.3.php');
}
// updates for v1.4. basically just cleans up meta table from 1.3 disaster.
if(version_compare($this->options['version'], '1.4', '<')) {
require_once('upgrades/update-1.4.php');
}
}
private function dump($val) {
echo "
";
var_dump($val);
echo "
";
}
public function current_screen() {
$screen = get_current_screen();
$args = array('format'=>'contextual_help');
$posts = $this->get_notes($args);
if(count($posts)) {
foreach($posts as $post) {
$c = apply_filters('dsn_contextual_help_content',$this->get_content($post),$post);
$c = "
{$c}
";
$t = $this->sanitize_title($post->post_title, $post->post_author);
$id = $post->ID;
$screen->add_help_tab( array(
'id' => "dsn-postid-{$id}",
'title' => apply_filters('dsn_contextual_help_title',$t,$post),
'content' => apply_filters('dsn_contextual_help_notice',$c,$post),
) );
}
}
}
public function shortcode($atts=array(), $content='') {
extract( shortcode_atts( array(
'id' => '',
'depth' => 99,
'excerpt' => false,
'content' => true,
'title' => true,
), $atts ) );
// make sure this note actually allows use in a shortcode
if($id && get_post_meta($id, '_dsn_shortcodable', true) == true) {
$post = get_post($id);
if($post) {
$c = $this->note_with_children($post,'',0,!$excerpt,$depth);
}
}
return apply_filters('dsn_shortcode_notice',$c);
}
public function enqueue_includes() {
wp_register_style($this->plugin_stylesheet_id, plugins_url('admin-dashboard-site-notes/admin-styles-1.4.0.css'));
wp_enqueue_style($this->plugin_stylesheet_id);
wp_register_script($this->plugin_script_id, plugins_url('admin-dashboard-site-notes/admin-scripts.js'), array('jquery') );
wp_enqueue_script($this->plugin_script_id);
}
// check if user is allowed to configure the plugin
// only super admins are allowed, unless DSN_ADMIN_CONFIG is true, in which case any admin is allowed
private function user_has_admin() {
$is_admin = is_super_admin() || (defined('DSN_ADMIN_CONFIG') && current_user_can('manage_options'));
return apply_filters('dsn_has_admin', $is_admin);
}
// get all wordpress roles, allowing them to be filtered by other plugins
private function get_roles() {
global $wp_roles;
if(!$wp_roles) {
return array();
}
$all_roles = $wp_roles->roles;
$editable_roles = apply_filters('editable_roles', $all_roles);
return $editable_roles;
}
// add the content type to the admin navigation
public function admin_menu() {
add_dashboard_page($this->options['manual_title'], $this->options['manual_nav'], 'read', $this->plugin_id, array($this,'admin_page'));
}
// echo the instruction manual
public function admin_page() {
echo "
';
return $output;
}
// recursively get the post and its children
public function note_with_children($post,$format,$depth=0,$full_post=false,$max_depth=5) {
$output = "
";
}
echo apply_filters('dsn_admin_notices',$output);
}
// Called on wordpress hook 'admin_init'
public function admin_init() {
add_meta_box('display-location-div', esc_html__('Note Options', DSNMANAGER_TEXTDOMAIN), array($this,'display_info_metabox'), 'dsn_note', 'normal', 'low');
add_action('save_post', array($this,'save_meta'));
$types = get_post_types();
foreach($types as $type=>$type_obj) {
if(!in_array($type,$this->exclude_types)) {
$this->post_types[$type] = get_post_type_object($type);
}
}
}
// save all of our meta fields
public function save_meta($post_id) {
// prevent wp from killing our custom fields during autosave by making sure our fields are getting submitted
if (!isset($_POST[$this->nonce_id])) {
return $post_id;
}
// double-check to make sure these fields only get saved on dsn_notes
if( !isset($_POST['post_type']) || $_POST['post_type'] != $this->post_type_name ) {
return $post_id;
}
// check nonce
$nonce_id = $this->nonce_id;
if(!wp_verify_nonce($_POST[$nonce_id],$nonce_id)) {
return $post_id;
}
if(is_array($_POST) && count($_POST)) {
/* TODO: instead of manually putting these both here and in meta box, come up with method for just doing it all in one place. just need to duplicate checkboxes as hidden fields with value 0(done), and then just accept any fields we find that start with our prefix */
// format/types:
$this->check_and_save_checkbox('loc_everywhere',$post_id);
$this->check_and_save_checkbox('dashboard_widget',$post_id);
$this->check_and_save_checkbox('instruction_manual',$post_id);
$this->check_and_save_checkbox('contextual_help',$post_id);
$this->check_and_save_checkbox('admin_notice',$post_id);
// miscellaneous options:
$this->check_and_save_checkbox('hide_title',$post_id);
$this->check_and_save_checkbox('hide_title_widget',$post_id);
$this->check_and_save_checkbox('hide_title_shortcode',$post_id);
$this->check_and_save_checkbox('shortcodable',$post_id);
// locations:
foreach($this->post_types as $type=>$type_obj) {
if($type =='revision') {
$this->check_and_save_checkbox("loc_view_".$type,$post_id);
$this->check_and_save_checkbox("loc_diff_".$type,$post_id);
}
else {
$this->check_and_save_checkbox("loc_edit_".$type,$post_id);
$this->check_and_save_checkbox("loc_new_".$type,$post_id);
$this->check_and_save_checkbox("loc_search_".$type,$post_id);
$this->check_and_save_checkbox("loc_all_".$type,$post_id);
}
}
// roles:
global $wp_roles;
$roles = $wp_roles->roles;
foreach($roles as $role_name=>$role_arr) {
$this->check_and_save_checkbox("role_".$role_name,$post_id);
}
}
}
// saves post data from checkboxes
public function check_and_save_checkbox($key,$post_id = null) {
if(!$post_id) {
global $post;
$post_id = $post->ID;
}
$key = $this->custom_field_prefix . $key;
if(isset($_POST[$key])) {
update_post_meta($post_id, $key, 1);
}
else {
// cut down on the number of useless meta keys we create in the db by never actually creating
// a negative... just set them to false if they've previously been created
if(get_post_meta($post_id, $key, true)) {
update_post_meta($post_id, $key, 0);
}
}
}
private function get_checkbox($key, $msg, $class='', $default_checked=false) {
$checked = '';
$key = $this->custom_field_prefix . $key;
if((isset($this->custom[$key][0]) && $this->custom[$key][0] == 1) || (!isset($this->custom[$key][0]) && $default_checked)) {
$checked = " checked='checked' ";
}
$class = esc_html($class);
$key = esc_html($key);
$msg = esc_html($msg);
$ret = "
" . esc_html__("Notes are sanitized by stripping all tag attributes and only allowing the following tags: %s. To remove sanitizing from administrator notes, uncheck the 'sanitize administrator html' checkbox. However, if users can change the author_id of a site note, it should remain checked.", DSNMANAGER_TEXTDOMAIN) . "
","<{$tag_html}>");
}
function plugin_options_validate($input) {
$options = get_option($this->plugin_id);
if(is_array($input)) {
foreach($input as $key=>$val) {
$options[$key] = $val;
}
// for each role, give/remove the edit capability
// TODO: this should really go in a 'save options' hook, but it works fine here for now
global $wp_roles;
$roles = $this->get_roles();
foreach($roles as $role=>$role_obj) {
if(isset($input['role_'.$role]) && $input['role_'.$role]) {
$wp_roles->add_cap($role, $this->post_type_name_cap,true);
foreach($this->capabilities as $c=>$val) {
$wp_roles->add_cap($role, $val, true);
}
}
else {
$wp_roles->add_cap($role, $this->post_type_name_cap,false);
foreach($this->capabilities as $c=>$val) {
$wp_roles->add_cap($role, $val, false);
}
}
}
}
$options = apply_filters('dsn_save_options', $options);
return $options;
}
// add the config page to the admin navigation under 'settings'
function add_config_menu() {
$admin_page_title = esc_html__("Site Notes Configuration", DSNMANAGER_TEXTDOMAIN);
$admin_nav_title = esc_html__("Site Notes", DSNMANAGER_TEXTDOMAIN);
add_options_page(esc_html($admin_page_title), esc_html($admin_nav_title), 'manage_options', $this->plugin_id, array($this,'options_page'));
}
// admin options page
function options_page() {
if(!$this->user_has_admin()) {
wp_die(esc_html__("You don't have permission to access this page.", DSNMANAGER_TEXTDOMAIN));
}
$admin_page_title = esc_html__("Site Notes Configuration", DSNMANAGER_TEXTDOMAIN);
?>