BuddyPress_First_Letter_Avatar

The BuddyPress First Letter Avatar BuddyPress First Letter Avatar class.

Defined (1)

The class is defined in the following location(s).

/buddypress-first-letter-avatar.php  
  1. class BuddyPress_First_Letter_Avatar { 
  2.  
  3. // Setup: 
  4. const MINIMUM_PHP = '5.4'; 
  5. const MINIMUM_WP = '4.6'; 
  6. const IMAGES_PATH = 'images'; // avatars root directory 
  7. const GRAVATAR_URL = 'https://secure.gravatar.com/avatar/'; // default url for gravatar 
  8. const PLUGIN_NAME = 'BuddyPress First Letter Avatar'; 
  9.  
  10. // Default configuration (this is the default configuration only for the first plugin use): 
  11. const USE_PROFILE_AVATAR = true; // TRUE: if user has his profile avatar, use it; FALSE: use custom avatars or Gravatars 
  12. const USE_GRAVATAR = true; // TRUE: if user has Gravatar, use it; FALSE: use custom avatars or user's profile avatar 
  13. const AVATAR_SET = 'default'; // directory where avatars are stored 
  14. const LETTER_INDEX = 0; // 0: first letter; 1: second letter; -1: last letter, etc. 
  15. const IMAGES_FORMAT = 'png'; // file format of the avatars 
  16. const ROUND_AVATARS = false; // TRUE: use rounded avatars; FALSE: dont use round avatars 
  17. const IMAGE_UNKNOWN = 'mystery'; // file name (without extension) of the avatar used for users with usernames beginning with symbol other than one from a-z range 
  18. const FILTER_PRIORITY = 10; // plugin filter priority 
  19.  
  20. // properties duplicating const values (will be changed in constructor after reading config from DB): 
  21. private $use_profile_avatar = self::USE_PROFILE_AVATAR; 
  22. private $use_gravatar = self::USE_GRAVATAR; 
  23. private $avatar_set = self::AVATAR_SET; 
  24. private $letter_index = self::LETTER_INDEX; 
  25. private $images_format = self::IMAGES_FORMAT; 
  26. private $round_avatars = self::ROUND_AVATARS; 
  27. private $image_unknown = self::IMAGE_UNKNOWN; 
  28. private $filter_priority = self::FILTER_PRIORITY; 
  29.  
  30.  
  31.  
  32. public function __construct() { 
  33.  
  34. /** --------------- CONFIGURATION --------------- */ 
  35.  
  36. // get plugin configuration from database: 
  37. $options = get_option('bpfla_settings'); 
  38. if (empty($options)) { 
  39. // no records in DB, use default (const) values to save plugin config: 
  40. $initial_settings = array( 
  41. 'bpfla_use_profile_avatar' => self::USE_PROFILE_AVATAR,  
  42. 'bpfla_use_gravatar' => self::USE_GRAVATAR,  
  43. 'bpfla_avatar_set' => self::AVATAR_SET,  
  44. 'bpfla_letter_index' => self::LETTER_INDEX,  
  45. 'bpfla_file_format' => self::IMAGES_FORMAT,  
  46. 'bpfla_round_avatars' => self::ROUND_AVATARS,  
  47. 'bpfla_unknown_image' => self::IMAGE_UNKNOWN,  
  48. 'bpfla_filter_priority' => self::FILTER_PRIORITY 
  49. ); 
  50. add_option('bpfla_settings', $initial_settings); 
  51. } else { // there are records in DB for our plugin 
  52. // and then assign them to our class properties (only if exsits in array): 
  53. $this->use_profile_avatar = (array_key_exists('bpfla_use_profile_avatar', $options) ? (bool)$options['bpfla_use_profile_avatar'] : false); 
  54. $this->use_gravatar = (array_key_exists('bpfla_use_gravatar', $options) ? (bool)$options['bpfla_use_gravatar'] : false); 
  55. $this->avatar_set = (array_key_exists('bpfla_avatar_set', $options) ? (string)$options['bpfla_avatar_set'] : self::AVATAR_SET); 
  56. $this->letter_index = (array_key_exists('bpfla_letter_index', $options) ? (int)$options['bpfla_letter_index'] : self::LETTER_INDEX); 
  57. $this->images_format = (array_key_exists('bpfla_file_format', $options) ? (string)$options['bpfla_file_format'] : self::IMAGES_FORMAT); 
  58. $this->round_avatars = (array_key_exists('bpfla_round_avatars', $options) ? (bool)$options['bpfla_round_avatars'] : false); 
  59. $this->image_unknown = (array_key_exists('bpfla_unknown_image', $options) ? (string)$options['bpfla_unknown_image'] : self::IMAGE_UNKNOWN); 
  60. $this->filter_priority = (array_key_exists('bpfla_filter_priority', $options) ? (int)$options['bpfla_filter_priority'] : self::FILTER_PRIORITY); 
  61.  
  62.  
  63. /** --------------- WP HOOKS --------------- */ 
  64.  
  65. // add plugins_loaded action to load textdomain: 
  66. add_action('plugins_loaded', array($this, 'plugins_loaded')); 
  67.  
  68. // add Settings link to plugins page: 
  69. add_filter('plugin_action_links_' . plugin_basename(__FILE__), array($this, 'add_settings_link')); 
  70.  
  71. // add plugin activation hook: 
  72. register_activation_hook(__FILE__, array($this, 'plugin_activate')); 
  73.  
  74. // add stylesheets/scripts: 
  75. add_action('wp_enqueue_scripts', array($this, 'enqueue_scripts')); 
  76.  
  77. // add filter to get_avatar: 
  78. add_filter('get_avatar', array($this, 'set_comment_avatar'), $this->filter_priority, 6); // this will only be used for anonymous WordPress comments (from non-users) 
  79.  
  80. // add filter to bp_core_fetch_avatar: 
  81. add_filter('bp_core_fetch_avatar', array($this, 'set_buddypress_avatar'), $this->filter_priority, 2); // this is used for every avatar call except the anonymous comment posters 
  82.  
  83. // filter just the avatar URL: 
  84. add_filter('bp_core_fetch_avatar_url', array($this, 'set_buddypress_avatar_url'), $this->filter_priority, 2); 
  85.  
  86. // add filter for wpDiscuz: 
  87. add_filter('wpdiscuz_author_avatar_field', array($this, 'set_wpdiscuz_avatar'), $this->filter_priority, 4); 
  88.  
  89. // when in admin, make sure first letter avatars are not displayed on discussion settings page: 
  90. if (is_admin()) { 
  91. global $pagenow; 
  92. if ($pagenow == 'options-discussion.php') { 
  93. remove_filter('get_avatar', array($this, 'set_comment_avatar'), $this->filter_priority); 
  94.  
  95.  
  96.  
  97.  
  98. /** 
  99. * Plugins loaded - load text domain 
  100. */ 
  101. public function plugins_loaded() { 
  102.  
  103. load_plugin_textdomain('buddypress-first-letter-avatar', FALSE, basename(dirname(__FILE__)) . '/languages/'); 
  104.  
  105.  
  106.  
  107.  
  108. /** 
  109. * Add scripts and stylesheets 
  110. */ 
  111. public function enqueue_scripts() { 
  112.  
  113. wp_enqueue_style('wpfla-style-handle', plugins_url('css/style.css', __FILE__)); 
  114.  
  115.  
  116.  
  117.  
  118. /** 
  119. * On plugin activation check WP and PHP version and if requirements are not met, disable the plugin and display error 
  120. */ 
  121. public function plugin_activate() { // plugin activation event 
  122.  
  123. $php = self::MINIMUM_PHP; 
  124. $wp = self::MINIMUM_WP; 
  125.  
  126. // check PHP and WP compatibility: 
  127. global $wp_version; 
  128. if (version_compare(PHP_VERSION, $php, '<')) 
  129. $flag = 'PHP'; 
  130. else if (version_compare($wp_version, $wp, '<')) 
  131. $flag = 'WordPress'; 
  132.  
  133. if (!empty($flag)) { 
  134. $version = 'PHP' == $flag ? $php : $wp; 
  135. deactivate_plugins(plugin_basename(__FILE__)); 
  136. $wrong_version_text = sprintf(__('<p>This plugin requires %s version %s or greater.</p>', 'buddypress-first-letter-avatar'), $flag, $version); 
  137. $wrong_version_message_title = __('Plugin Activation Error', 'buddypress-first-letter-avatar'); 
  138. wp_die($wrong_version_text, $wrong_version_message_title, array('response' => 200, 'back_link' => true)); 
  139.  
  140.  
  141.  
  142.  
  143. /** 
  144. * Add Settings link to Plugins section 
  145. */ 
  146. public function add_settings_link($links) { 
  147.  
  148. // add localised Settings link do plugin settings on plugins page: 
  149. $settings_link = '<a href="options-general.php?page=buddypress_first_letter_avatar">'.__('Settings', 'buddypress-first-letter-avatar').'</a>'; 
  150. array_unshift($links, $settings_link); 
  151.  
  152. return $links; 
  153.  
  154.  
  155.  
  156.  
  157. /** 
  158. * This is method is used to filter wpDiscuz parameter - it feeds $comment object to get_avatar() function 
  159. * (more on line 102 in wpdiscuz/templates/comment/class.WpdiscuzWalker.php) 
  160. */ 
  161. public function set_wpdiscuz_avatar($author_avatar_field, $comment, $user, $profile_url) { 
  162.  
  163. // that's all we need - instead of user ID or guest email supplied in 
  164. // $author_avatar_field, we just need to return the $comment object 
  165. return $comment; 
  166.  
  167.  
  168.  
  169.  
  170. /** 
  171. * This method is used only for guest comments (BP filters do not filter guest avatars) 
  172. * It returns a full HTML <img /> tag with avatar (first letter or Gravatar) 
  173. */ 
  174. public function set_comment_avatar($avatar, $id_or_email, $size = '96', $default = '', $alt = '', $args = array()) { 
  175.  
  176. // create two main variables: 
  177. $name = ''; 
  178. $email = ''; 
  179. $user = null; // we will try to assign User object to this 
  180.  
  181. if (is_object($id_or_email)) { // id_or_email can actually be also a comment object, so let's check it first 
  182. if (!empty($id_or_email->comment_ID)) { 
  183. $comment_id = $id_or_email->comment_ID; // it is a comment object and we can take the ID 
  184. } else { 
  185. $comment_id = null; 
  186. } else { 
  187. $comment_id = null; 
  188.  
  189. if ($comment_id === null) { // if it's not a regular comment, use $id_or_email to get more data 
  190.  
  191. if (is_numeric($id_or_email)) { // if id_or_email represents user id, get user by id 
  192. $id = (int) $id_or_email; 
  193. $user = get_user_by('id', $id); 
  194. } else if (is_object($id_or_email)) { // if id_or_email represents an object 
  195. if (!empty($id_or_email->user_id)) { // if we can get user_id from the object, get user by id 
  196. $id = (int) $id_or_email->user_id; 
  197. $user = get_user_by('id', $id); 
  198.  
  199. if (!empty($user) && is_object($user)) { // if commenter is a registered user... (technically it's not possible, since ... 
  200. $name = $user->data->display_name; // ... this method is only called when unregistered user writes comments, but it's still worth checking) 
  201. $email = $user->data->user_email; 
  202. } else if (is_string($id_or_email)) { // if string was supplied 
  203. if (!filter_var($id_or_email, FILTER_VALIDATE_EMAIL)) { // if it is NOT email, it must be a username 
  204. $name = $id_or_email; 
  205. } else { // it must be email 
  206. $email = $id_or_email; 
  207. $user = get_user_by('email', $email); 
  208. } else { // if commenter is not a registered user, we have to try various fallbacks 
  209. $post_id = get_the_ID(); 
  210. if ($post_id !== null) { // if this actually is a post... 
  211. $post_data = array('name' => '', 'email' => ''); 
  212. // first we try for bbPress: 
  213. $post_data['name'] = get_post_meta($post_id, '_bbp_anonymous_name', true); 
  214. $post_data['email'] = get_post_meta($post_id, '_bbp_anonymous_email', true); 
  215. if (!empty($post_data)) { // we have some post data... 
  216. $name = $post_data['name']; 
  217. $email = $post_data['email']; 
  218. } else { // nothing else to do, assign email from id_or_email to email and later use it as name 
  219. if (!empty($id_or_email)) { 
  220. $email = $id_or_email; 
  221.  
  222. } else { // if it's a standard comment, use basic comment functions to retrieve info 
  223.  
  224. $comment = $id_or_email; 
  225.  
  226. if (!empty($comment->comment_author)) { 
  227. $name = $comment->comment_author; 
  228. } else { 
  229. $name = get_comment_author(); 
  230.  
  231. if (!empty($comment->comment_author_email)) { 
  232. $email = $comment->comment_author_email; 
  233. } else { 
  234. $email = get_comment_author_email(); 
  235.  
  236.  
  237. if (empty($name) && !empty($user) && is_object($user)) { // if we do not have the name, but we have user object 
  238. $name = $user->display_name; 
  239.  
  240. if (empty($email) && !empty($user) && is_object($user)) { // if we do not have the email, but we have user object 
  241. $email = $user->user_email; 
  242.  
  243. // check whether Gravatar should be used at all: 
  244. if ($this->use_gravatar == true) { 
  245. $gravatar_uri = $this->generate_gravatar_uri($email, $size); 
  246. $first_letter_uri = $this->generate_first_letter_uri($name, $size); 
  247. $avatar_uri = $gravatar_uri . '&default=' . urlencode($first_letter_uri); 
  248. } else { 
  249. // gravatar is not used: 
  250. $first_letter_uri = $this->generate_first_letter_uri($name, $size); 
  251. $avatar_uri = $first_letter_uri; 
  252.  
  253. $avatar_img_output = $this->generate_avatar_img_tag($avatar_uri, $size, $alt, $args); // get final <img /> tag for the avatar/gravatar 
  254.  
  255. return $avatar_img_output; 
  256.  
  257.  
  258.  
  259.  
  260. /** 
  261. * This method is used to filter just the avatar URL. Basically the same as set_buddypress_avatar(),  
  262. * but it does not return the full <img /> tag, it just returns the image URL 
  263. */ 
  264. public function set_buddypress_avatar_url($image_url = '', $params = array()) { 
  265.  
  266. $user_id = $params['item_id']; 
  267. $size = $params['width']; 
  268. $email = $params['email']; 
  269.  
  270. if (!is_numeric($user_id)) { // user_id was not passed, so we cannot do anything about this avatar 
  271. return $image_url; 
  272.  
  273. // if there is no gravatar URL, it means that user has set his own profile avatar,  
  274. // so we're gonna see if we should be using it (user avatar); 
  275. // if we should, just return the input data and leave the avatar as it was: 
  276. if ($this->use_profile_avatar == true) { 
  277. if (stripos($image_url, 'gravatar.com/avatar') === false) { // we need to specifically check for false (hence '===') 
  278. return $image_url; 
  279.  
  280. $user = get_user_by('id', $user_id); 
  281.  
  282. if (empty($size)) { // if for some reason size was not specified... 
  283. $size = 48; // just set it to 48 
  284.  
  285. $name = $user->data->display_name; 
  286.  
  287. if (empty($email)) { // email was not supplied with parameters 
  288. $email = $user->data->user_email; // get it by user id 
  289.  
  290. if (empty($name)) { 
  291. $name = bp_core_get_username($user_id); // BuddyPress fallback 
  292.  
  293. if (empty($name)) { 
  294. $name = $user->data->user_nicename; // another fallback (to WP nicename) 
  295.  
  296. $first_letter_uri = $this->generate_first_letter_uri($name, $size); // get letter URL 
  297.  
  298. // check whether Gravatar should be used at all: 
  299. if ($this->use_gravatar == true && !empty($email)) { // if we should use gravatar and we have email 
  300. $gravatar_uri = $this->generate_gravatar_uri($email, $size); 
  301. $image_url = $gravatar_uri . '&default=' . urlencode($first_letter_uri); 
  302. } else { // gravatar not used or we do not have email 
  303. $image_url = $first_letter_uri; 
  304.  
  305. return $image_url; 
  306.  
  307.  
  308.  
  309.  
  310. /** 
  311. * This method is used to filter every avatar, except for anonymous comments. 
  312. * It returns full <img /> HTML tag 
  313. */ 
  314. public function set_buddypress_avatar($html_data = '', $params = array()) { 
  315.  
  316. if (empty($params)) { // data not supplied 
  317. return $html_data; // return original image 
  318.  
  319. // Create HTML object to get some data out of the image supplied: 
  320. $html_doc = new DOMDocument(); 
  321. $html_doc->loadHTML($html_data); 
  322. $image = $html_doc->getElementsByTagName('img'); 
  323. if (empty($image)) { // if there is no image... 
  324. return $html_data; 
  325.  
  326. $original_image_url = ''; // define variable before loop 
  327. foreach ($image as $image_data) { // we are using foreach, but in fact there should be only one image 
  328. /** @var $image_data DOMNodeList */ 
  329. $original_image_url = $image_data->getAttribute('src'); // url of the original image 
  330. break; // this foreach loop should be exectued only once no matter what, since there is only one img tag, but just to be safe we are going to use break here 
  331.  
  332. // these params are very well documented in BuddyPress' bp-core-avatar.php file: 
  333. $id = $params['item_id']; 
  334. $object = $params['object']; 
  335. $size = $params['width']; 
  336. $alt = $params['alt']; 
  337. $email = $params['email']; 
  338.  
  339. if ($object == 'user') { // if we are filtering user's avatar 
  340.  
  341. // if there is no gravatar URL, it means that user has set his own profile avatar,  
  342. // so we're gonna see if we should be using it (user avatar); 
  343. // if we should, just return the input data and leave the avatar as it was 
  344. // (2nd condition explanation -> check 'group' case) 
  345. if ($this->use_profile_avatar == true) { 
  346. if ((stripos($original_image_url, 'gravatar.com/avatar') === false) && // we need to specifically check for false (hence '===') 
  347. (stripos($original_image_url, 'bp-core/images/mystery-man') === false)) { // no extension specified just in case 
  348. return $html_data; 
  349.  
  350. if (empty($id) && $id !== 0) { // if id not specified (and id not equal 0) 
  351. if (is_user_logged_in()) { // if user logged in 
  352. $user = get_user_by('id', get_current_user_id()); 
  353. $id = get_current_user_id(); // get current user's id 
  354. } else { 
  355. return $html_data; // no id specified and user not logged in - return the original image 
  356.  
  357. $user = get_user_by('id', $id); // let's get user object from DB 
  358.  
  359. if (empty($size)) { // if for some reason size was not specified... 
  360. $size = 48; // just set it to 48 
  361.  
  362. if (empty($alt)) { 
  363. $alt = __('Profile Photo', 'buddypress'); 
  364.  
  365. if (empty($email)) { // if for some reason email was not specified 
  366. $email = $user->data->user_email; // get it by user id 
  367.  
  368. $name = $user->data->display_name; 
  369. if (empty($name)) { 
  370. $name = bp_core_get_username($id); // BuddyPress fallback 
  371. if (empty($name)) { 
  372. $name = $user->data->user_nicename; // another fallback (to WP nicename) 
  373.  
  374. } else if ($object == 'group') { // we're filtering group 
  375.  
  376. if (empty($id) && $id !== 0) { // if for some reason there is no id 
  377. return $html_data; 
  378.  
  379. $group = groups_get_group(array('group_id' => $id)); // get the Group object by ID 
  380.  
  381. if (empty($group)) { // if for some reason group is empty/does not exist/etc. 
  382. return $html_data; // return the input data 
  383.  
  384. // we are using the same way to determine whether group has avatar set as we did with user avatars 
  385. // if there is no gravatar URL, it means that group has their own avatar,  
  386. // so we're gonna see if we should be using it (user/group avatar); 
  387. // if we should, just return the input data and leave the avatar as it was. 
  388. // it is also possible that group's mystery avatar is stored locally, so 
  389. // we need to check that as well 
  390. if ($this->use_profile_avatar == true) { 
  391. if ((stripos($original_image_url, 'gravatar.com/avatar') === false) && // we need to specifically check for false (hence '===') 
  392. (stripos($original_image_url, 'bp-core/images/mystery-group') === false)) { // no extension specified just in case 
  393. return $html_data; 
  394.  
  395. if (empty($group->name)) { // if for some reason there is no name 
  396. return $html_data; 
  397.  
  398. $name = $group->name; 
  399.  
  400. if (empty($size)) { // if for some reason size was not specified... 
  401. $size = 96; // just set it to 96 
  402.  
  403. if (empty($alt)) { 
  404. $alt = __('Group logo of %s', 'buddypress'); 
  405.  
  406. } else if ($object == 'blog') { // we're filtering blog 
  407.  
  408. return $html_data; // this feature is not used at all, so just return the input parameter 
  409.  
  410. } else { // not user, not group and not blog - just return the input html image 
  411.  
  412. return $html_data; 
  413.  
  414.  
  415. $first_letter_uri = $this->generate_first_letter_uri($name, $size); // get letter URL 
  416.  
  417. // check whether Gravatar should be used at all: 
  418. if ($this->use_gravatar == true && !empty($email)) { // if we should user gravatar and we have email 
  419. $gravatar_uri = $this->generate_gravatar_uri($email, $size); 
  420. $avatar_uri = $gravatar_uri . '&default=' . urlencode($first_letter_uri); 
  421. } else { // gravatar not used or we do not have email 
  422. $avatar_uri = $first_letter_uri; 
  423.  
  424. $avatar_img_output = $this->generate_avatar_img_tag($avatar_uri, $size, $alt); // get final <img /> tag for the avatar/gravatar 
  425.  
  426. return $avatar_img_output; 
  427.  
  428.  
  429.  
  430.  
  431. /** 
  432. * Generate full HTML <img /> tag with avatar URL, size, CSS classes etc. 
  433. */ 
  434. private function generate_avatar_img_tag($avatar_uri, $size, $alt = '', $args = array()) { 
  435.  
  436. // Default classes 
  437. $css_classes = 'avatar avatar-' . $size . ' photo'; 
  438.  
  439. // Append plugin class 
  440. $css_classes .= ' bpfla'; 
  441.  
  442. // prepare extra classes for <img> tag depending on plugin settings: 
  443. if ($this->round_avatars == true) { 
  444. $css_classes .= ' round-avatars'; 
  445.  
  446. // Append extra classes 
  447. if (array_key_exists('class', $args)) { 
  448. if (is_array($args['class'])) { 
  449. $css_classes .= ' ' . implode(' ', $args['class']); 
  450. } else { 
  451. $css_classes .= ' ' . $args['class']; 
  452.  
  453. $output_data = "<img alt='{$alt}' src='{$avatar_uri}' class='{$css_classes}' width='{$size}' height='{$size}' />"; 
  454.  
  455. // return the complete <img> tag: 
  456. return $output_data; 
  457.  
  458.  
  459.  
  460.  
  461. /** 
  462. * This method generates full URL for letter avatar (for example http://yourblog.com/wp-content/plugins/buddypress-first-letter-avatar/images/default/96/k.png),  
  463. * according to the $name and $size provided 
  464. */ 
  465. private function generate_first_letter_uri($name, $size) { 
  466.  
  467. // get picture filename (and lowercase it) from commenter name: 
  468. if (empty($name)) { // if, for some reason, the name is empty, set file_name to default unknown image 
  469.  
  470. $file_name = $this->image_unknown; 
  471.  
  472. } else { // name is not empty, so we can proceed 
  473.  
  474. $file_name = substr($name, $this->letter_index, 1); // get one letter counting from letter_index 
  475. $file_name = strtolower($file_name); // lowercase it... 
  476.  
  477. if (extension_loaded('mbstring')) { // check if mbstring is loaded to allow multibyte string operations 
  478. $file_name_mb = mb_substr($name, $this->letter_index, 1); // repeat, this time with multibyte functions 
  479. $file_name_mb = mb_strtolower($file_name_mb); // and again... 
  480. } else { // mbstring is not loaded - we're not going to worry about it, just use the original string 
  481. $file_name_mb = $file_name; 
  482.  
  483. // couple of exceptions: 
  484. if ($file_name_mb == '*') { 
  485. $file_name = 'a'; 
  486. $file_name_mb = 'a'; 
  487. } else if ($file_name_mb == '*') { 
  488. $file_name = 'c'; 
  489. $file_name_mb = 'c'; 
  490. } else if ($file_name_mb == '*') { 
  491. $file_name = 'e'; 
  492. $file_name_mb = 'e'; 
  493. } else if ($file_name_mb == '*') { 
  494. $file_name = 'n'; 
  495. $file_name_mb = 'n'; 
  496. } else if ($file_name_mb == '') { 
  497. $file_name = 'o'; 
  498. $file_name_mb = 'o'; 
  499. } else if ($file_name_mb == '*') { 
  500. $file_name = 's'; 
  501. $file_name_mb = 's'; 
  502. } else if ($file_name_mb == '*' || $file_name_mb == '*') { 
  503. $file_name = 'z'; 
  504. $file_name_mb = 'z'; 
  505.  
  506. // create arrays with allowed character ranges: 
  507. $allowed_numbers = range(0, 9); 
  508. foreach ($allowed_numbers as $number) { // cast each item to string (strict param of in_array requires same type) 
  509. $allowed_numbers[$number] = (string)$number; 
  510. $allowed_letters_latin = range('a', 'z'); 
  511. $allowed_letters_cyrillic = range('*', '*'); 
  512. $allowed_letters_arabic = range('*', '*'); 
  513. // check if the file name meets the requirement; if it doesn't - set it to unknown 
  514. $charset_flag = ''; // this will be used to determine whether we are using latin chars, cyrillic chars, arabic chars or numbers 
  515. // check whther we are using latin/cyrillic/numbers and set the flag, so we can later act appropriately: 
  516. if (in_array($file_name, $allowed_numbers, true)) { 
  517. $charset_flag = 'number'; 
  518. } else if (in_array($file_name, $allowed_letters_latin, true)) { 
  519. $charset_flag = 'latin'; 
  520. } else if (in_array($file_name, $allowed_letters_cyrillic, true)) { 
  521. $charset_flag = 'cyrillic'; 
  522. } else if (in_array($file_name, $allowed_letters_arabic, true)) { 
  523. $charset_flag = 'arabic'; 
  524. } else { // for some reason none of the charsets is appropriate 
  525. $file_name = $this->image_unknown; // set it to unknown 
  526.  
  527. if (!empty($charset_flag)) { // if charset_flag is not empty, i.e. flag has been set to latin, number or cyrillic... 
  528. switch ($charset_flag) { // run through various options to determine the actual filename for the letter avatar 
  529. case 'number': 
  530. $file_name = 'number_' . $file_name; 
  531. break; 
  532. case 'latin': 
  533. $file_name = 'latin_' . $file_name; 
  534. break; 
  535. case 'cyrillic': 
  536. $temp_array = unpack('V', iconv('UTF-8', 'UCS-4LE', $file_name_mb)); // beautiful one-liner by @bobince from SO - http://stackoverflow.com/a/27444149/4848918 
  537. $unicode_code_point = $temp_array[1]; 
  538. $file_name = 'cyrillic_' . $unicode_code_point; 
  539. break; 
  540. case 'arabic': 
  541. $temp_array = unpack('V', iconv('UTF-8', 'UCS-4LE', $file_name_mb)); 
  542. $unicode_code_point = $temp_array[1]; 
  543. $file_name = 'arabic_' . $unicode_code_point; 
  544. break; 
  545. default: 
  546. $file_name = $this->image_unknown; // set it to uknknown 
  547. break; 
  548.  
  549.  
  550. // detect most appropriate size based on WP avatar size: 
  551. if ($size <= 48) $custom_avatar_size = '48'; 
  552. else if ($size > 48 && $size <= 96) $custom_avatar_size = '96'; 
  553. else if ($size > 96 && $size <= 128) $custom_avatar_size = '128'; 
  554. else if ($size > 128 && $size <= 256) $custom_avatar_size = '256'; 
  555. else $custom_avatar_size = '512'; 
  556.  
  557. // create file path - $avatar_uri variable will look something like this: 
  558. // http://yourblog.com/wp-content/plugins/buddypress-first-letter-avatar/images/default/96/k.png): 
  559. $avatar_uri = 
  560. plugins_url() . '/' 
  561. . dirname(plugin_basename(__FILE__)) . '/' 
  562. . self::IMAGES_PATH . '/' 
  563. . $this->avatar_set . '/' 
  564. . $custom_avatar_size . '/' 
  565. . $file_name . '.' 
  566. . $this->images_format; 
  567.  
  568. // return the final first letter image url: 
  569. return $avatar_uri; 
  570.  
  571.  
  572.  
  573.  
  574. /** 
  575. * This method generates full URL for Gravatar, according to the $email and $size provided 
  576. */ 
  577. private function generate_gravatar_uri($email, $size = '96') { 
  578.  
  579. if (!filter_var($email, FILTER_VALIDATE_EMAIL)) { // if email not correct 
  580. $email = ''; // set it to empty string 
  581.  
  582. // email to gravatar url: 
  583. $avatar_uri = self::GRAVATAR_URL; 
  584. $avatar_uri .= md5(strtolower(trim($email))); 
  585. $avatar_uri .= "?s={$size}&r=g"; 
  586.  
  587. return $avatar_uri; 
  588.  
  589.  
  590.  
  591.  
  592. /** 
  593. * This method is not used, but I'm keeping it since it may be useful. 
  594. * This method generates a clean gravatar URL from any kind of gravatar URL. It's useful, because it allows to control exactly how the Gravatar URL looks like. 
  595. * It basically strips any parameters and makes sure that the gravatar URL always has the same format (for example https://secure.gravatar.com/avatar/) 
  596. */ 
  597. /** 
  598. private function generate_gravatar_uri_from_gravatar_url($gravatar_inital_uri) { // this method is needed to make sure we control how the gravatar uri looks like 
  599.   
  600. // before we start anything, we need to get the actual size from the displayed gravatar: 
  601. $url_parts = parse_url($gravatar_inital_uri); 
  602. if (!empty($url_parts['query'])) { 
  603. parse_str($url_parts['query'], $url_query); 
  604. if (!empty($url_query['s'])) { 
  605. $size = $url_query['s']; 
  606. } else if (!empty($url_query['size'])) { 
  607. $size = $url_query['size']; 
  608. } else { 
  609. $size = '96'; 
  610. } else { 
  611. $size = '96'; 
  612.   
  613. // first let's strip all get parameters: 
  614. $gravatar_uri_array = explode('?', $gravatar_inital_uri); 
  615. $gravatar_uri = $gravatar_uri_array[0]; 
  616.   
  617. $gravatar_uri = strtolower($gravatar_uri); // lowercase the whole url 
  618.   
  619. $possible_starts = array( // possible ways of how the url may start 
  620. 'https://secure.gravatar.com/avatar/',  
  621. 'https://www.gravatar.com/avatar/',  
  622. 'https://gravatar.com/avatar/',  
  623. 'http://secure.gravatar.com/avatar/',  
  624. 'http://www.gravatar.com/avatar/',  
  625. 'http://gravatar.com/avatar/',  
  626. '//secure.gravatar.com/avatar/',  
  627. '//www.gravatar.com/avatar/',  
  628. '//gravatar.com/avatar/' 
  629. ); 
  630.   
  631. $gravatar_hash = ''; 
  632.   
  633. foreach ($possible_starts as $possible_start) { 
  634. if (strpos($gravatar_uri, $possible_start) === 0) { // if starts with this string... 
  635. $gravatar_hash = str_replace($possible_start, '', $gravatar_uri); // we need to remove the possible url beginning, so that we are left with just the md5 gravatar hash 
  636. break; // since we have found what we needed, we can cancel loop execution 
  637.   
  638. // now we have the just the md5 hash, so we can construct the gravatar uri exactly the way we want: 
  639. $avatar_uri = self::GRAVATAR_URL; 
  640. $avatar_uri .= $gravatar_hash; 
  641. $avatar_uri .= "?s={$size}&r=g"; 
  642.   
  643. return $avatar_uri; 
  644.   
  645. */ 
  646.  
  647.