{"id":398813,"date":"2026-11-06T17:15:27","date_gmt":"2026-11-06T17:15:27","guid":{"rendered":"https:\/\/wordpress.org\/plugins\/bani-honar-toolkit\/"},"modified":"2026-11-06T17:15:06","modified_gmt":"2026-11-06T17:15:06","slug":"bani-honar-toolkit","status":"publish","type":"plugin","link":"https:\/\/wordpress.org\/plugins\/bani-honar-toolkit\/","author":23591987,"comment_status":"closed","ping_status":"closed","template":"","meta":{"version":"1.0.0","stable_tag":"1.0.0","tested":"7.1.4","requires":"5.8","requires_php":"7.4","requires_plugins":null,"header_name":"Bani Honar Toolkit","header_author":"Bani Honar Advertising Agency","header_description":"A multi-purpose, modular and extensible WordPress plugin: link shortener, QR code generator, page shield, visitor statistics, post duplicator, local profile pictures and more.","assets_banners_color":"10479b","last_updated":"2026-11-06 17:15:06","external_support_url":"","external_repository_url":"","donate_link":"","header_plugin_uri":"","header_author_uri":"https:\/\/banihonarpars.ir","rating":0,"author_block_rating":0,"active_installs":0,"downloads":50,"num_ratings":0,"support_threads":0,"support_threads_resolved":0,"author_block_count":0,"sections":["description","installation","faq","changelog"],"tags":{"1.0.0":{"tag":"1.0.0","author":"banihonar","date":"2026-11-06 17:15:06","revision":3788433}},"upgrade_notice":{"1.0.0":"<p>First public release. If you test an earlier internal build, replace it with this one; your data is kept. The online country lookup in Visitor Stats is off until you switch it on.<\/p>"},"ratings":[],"assets_icons":{"icon-256x256.png":{"filename":"icon-256x256.png","revision":3788391,"resolution":"256x256","location":"assets","locale":"","width":256,"height":256}},"assets_banners":{"banner-1544x500.png":{"filename":"banner-1544x500.png","revision":3788391,"resolution":"1544x500","location":"assets","locale":"","width":1544,"height":500}},"assets_blueprints":{},"all_blocks":[],"tagged_versions":["1.0.0"],"block_files":[],"assets_screenshots":[],"screenshots":{"1":"The dashboard with one card and switch per module.","2":"Creating a short link and the list of links with click counts.","3":"The QR code generator.","4":"Settings: plugin language, redirect type and more.","5":"The profile picture card on the user profile screen.","6":"Visitor Stats: overview with chart, countries, sources and devices.","7":"Visitor Stats: the visit log with IP address, country and device name.","8":"Page Shield on its own tab with an on\/off switch.","9":"The Contact tab."}},"plugin_section":[],"plugin_tags":[23177,291230,1373,5530,10933],"plugin_category":[],"plugin_contributors":[291231],"plugin_business_model":[],"class_list":["post-398813","plugin","type-plugin","status-publish","hentry","plugin_tags-duplicate-post","plugin_tags-page-shield","plugin_tags-qr-code","plugin_tags-url-shortener","plugin_tags-visitor-statistics","plugin_contributors-banihonar","plugin_committers-banihonar"],"banners":[],"icons":{"svg":false,"icon":"https:\/\/ps.w.org\/bani-honar-toolkit\/assets\/icon-256x256.png?rev=3788391","icon_2x":"https:\/\/ps.w.org\/bani-honar-toolkit\/assets\/icon-256x256.png?rev=3788391","generated":false},"screenshots":[],"raw_content":"<!--section=description-->\n<p>Bani Honar Toolkit is a small, modular plugin. Every feature is a module that you can switch on or off from one dashboard, and developers can add their own modules.<\/p>\n\n<p><strong>Included modules<\/strong><\/p>\n\n<ul>\n<li><strong>Link Shortener<\/strong> - turn long addresses into short links on your own domain, for example <code>banihonar.com\/Ab33<\/code>.\n\n<ul>\n<li>Random codes made of lowercase letters, uppercase letters and numbers. You choose the length, from 1 to 32 characters.<\/li>\n<li>Or type your own custom code. Codes are case-sensitive: <code>Ab<\/code> and <code>ab<\/code> are different links.<\/li>\n<li>Click counter and last-click time for every link, search, edit and delete.<\/li>\n<li>Redirect type (302, 307 or 301) and an optional path prefix such as <code>\/go\/<\/code>.<\/li>\n<li>A short link never hides a real page of your site. It only works when WordPress finds nothing else at that address.<\/li>\n<\/ul><\/li>\n<li><strong>QR Code Generator<\/strong> - turn a link or any text into a QR code and download it as PNG or SVG.\n\n<ul>\n<li>Choose the size, error-correction level, border and colors. Persian text works too.<\/li>\n<li>Pick one of your short links, or press the QR button next to a link in the Link Shortener list.<\/li>\n<li>The code is created in your browser. Nothing is uploaded to an outside service or stored.<\/li>\n<\/ul><\/li>\n<li><strong>Visitor Stats<\/strong> (off by default) - see every visit to your website: how many, where from, from which IP address and country, and on which device.\n\n<ul>\n<li>Overview with a chart, totals (page views, visitors, visits, online now) and lists of countries, sources, device types, phone and tablet models, operating systems, browsers, campaigns and most viewed pages.<\/li>\n<li>Sources are recognised: direct, search engines, social networks and messengers (Instagram, Telegram, Eitaa, Rubika, Bale and more), other websites and <code>utm_<\/code> campaigns.<\/li>\n<li>Device details: brand and model (for example Samsung Galaxy A54 5G), system and version, browser and version, screen size, language and time zone. Chrome on Android hides the phone model from websites, so it is read through Client Hints; an iPhone model cannot be read by any website, so its family is shown.<\/li>\n<li>Visit log with search, filters (click any value to filter by it), details for every visit, and CSV download that opens correctly in Excel.<\/li>\n<li>Words visitors typed into the search box of your website, and the member (name and e-mail) behind a visit when the visitor is logged in to your site.<\/li>\n<li>Block an IP address or an IPv4 range for an hour, a day, a week, a month or until you remove it. Your own address and logged-in administrators are never blocked.<\/li>\n<li>Persian (Jalali) or Gregorian dates, a retention period, and a list of IP addresses that are never counted.<\/li>\n<li>Works with page-caching plugins and sets no cookies. Your own visits are not counted while you are logged in as an administrator.<\/li>\n<\/ul><\/li>\n<li><strong>Post Duplicator<\/strong> - copy any post, page or custom content with one click, and edit a live page safely.\n\n<ul>\n<li>\"Duplicate\" under every title in the lists, in the bulk actions menu, in the admin bar and in a box in the editor. The copy is a draft.<\/li>\n<li>Copies the content, excerpt, featured image, categories, tags and other taxonomies (in their saved order), custom fields, page template and post format. Comments, sub-pages (up to 100 posts), password, address, date, author and status are optional.<\/li>\n<li>Safe with page builders: backslashes in blocks and Elementor data are kept exactly, edit locks and page-builder caches are not copied, and copying does not put a page in the translation group of Polylang.<\/li>\n<li><strong>Edit safely<\/strong>: for a page that is already live, work on a hidden draft while visitors keep seeing the live page, then press \"Publish into the live page\". The address, date, status, author and comments of the live page stay, and its old text is saved as a revision. If the live page was changed after the draft was made, you are asked before anything is overwritten.<\/li>\n<li>A title pattern with <code>{title}<\/code>, <code>{n}<\/code> and <code>{date}<\/code>, a choice of who may duplicate, the content types it works for, and lists of custom fields and taxonomies that are never copied. Its own tab with a switch that turns it fully on or off.<\/li>\n<li>Nobody can copy what they are not allowed to read; people who may not publish get \"pending review\" copies. WooCommerce products and orders are left to WooCommerce, because they keep data in extra tables.<\/li>\n<\/ul><\/li>\n<li><strong>Page Shield<\/strong> (off by default) - makes casual copying of your pages harder. It has its own tab with a switch that turns it fully on or off. Every option is off until you tick it, and none of them has any effect on search engines.\n\n<ul>\n<li>Blocks the right-click menu (it still works in text fields), F12, Ctrl+U, Ctrl+S and Ctrl+Shift+I \/ J \/ C, and dragging images out of the page.<\/li>\n<li>Hides WordPress version details from the page head.<\/li>\n<li>Can also protect logged-in administrators (off by default, so you can inspect your own site).<\/li>\n<li>These are deterrents, not a lock: a browser must receive a page's HTML, CSS and JavaScript, so a determined person can always read them. Your PHP code never reaches the browser. The Elementor editor is not affected, and search engines see exactly the same page as everyone else. Options that could lower your search ranking, such as blocking text selection or covering the page, are deliberately not offered.<\/li>\n<\/ul><\/li>\n<li><strong>Contact the IT team<\/strong> - a tab where you can send a suggestion, criticism, a problem report, a security report or a request for a new module to it@banihonarpars.ir. Nothing is sent by your website: each card opens Gmail in a new tab, or the e-mail program of your computer, with a ready subject and text, and has a button that copies the whole message so you can send it from any e-mail service. A problem report adds only the versions of the toolkit, WordPress and PHP, the language and the list of active modules.<\/li>\n<li><strong>Profile Pictures<\/strong> - every user uploads a profile picture from the WordPress profile screen. No Gravatar account is needed, and nothing is requested from Gravatar.\n\n<ul>\n<li>JPG, PNG, GIF and WebP, up to 2 MB. Pictures are cropped to a small square automatically.<\/li>\n<\/ul><\/li>\n<\/ul>\n\n<p><strong>Two languages, one switch<\/strong><\/p>\n\n<p>The plugin screens can be shown in <strong>Persian (RTL)<\/strong> or <strong>English (LTR)<\/strong>, whatever your site language is. Change it under Bani Honar Toolkit &gt; Settings.<\/p>\n\n<p><strong>For developers<\/strong><\/p>\n\n<p>Extend <code>BHTK_Module<\/code> and register your module on the <code>bhtk_register_modules<\/code> action. It gets a dashboard card, an on\/off switch and its own section on the Settings screen.<\/p>\n\n<pre><code>add_action( 'bhtk_register_modules', function ( $plugin ) { $plugin-&gt;register_module( new My_Module() ); } );\n<\/code><\/pre>\n\n<p>Use the <code>bhtk_capability<\/code> filter to change the capability needed to use the toolkit (default: <code>manage_options<\/code>).<\/p>\n\n<p><strong>Third-party code<\/strong><\/p>\n\n<p>The QR Code Generator uses the MIT-licensed \"QR Code Generator for JavaScript\" by Kazuhiko Arase (version 2.0.4), included in <code>assets\/js\/vendor\/<\/code>. QR Code is a registered trademark of DENSO WAVE INCORPORATED.<\/p>\n\n<p><strong>Privacy and external services<\/strong><\/p>\n\n<p>The Post Duplicator stores no personal data. It marks copies and safe-edit drafts with four small custom fields (<code>_bhtk_clone_of<\/code>, <code>_bhtk_fork_of<\/code>, <code>_bhtk_open_fork<\/code>, <code>_bhtk_fork_time<\/code>) that hold post numbers and a time; they are removed when you delete all toolkit data.<\/p>\n\n<p>The link shortener stores, for each link: the code, the destination, an optional note, the click count, the time of the last click, who created it and when. Visitors are not identified or logged by it.<\/p>\n\n<p>The Visitor Stats module is off by default. While it is on, one small request is sent from the visitor's browser to your own website for every page opened (at most 600 views a minute are recorded for the whole site; developers can change this with the <code>bhtk_visits_max_per_minute<\/code> filter), and your site stores: the date and time, the IP address (or the address with its last part removed, if you choose so), the country, the page address and title, the referring website, campaign tags (<code>utm_<\/code>), the browser's User-Agent text and the device details derived from it, screen size, language and time zone. A random session code lives in the browser's sessionStorage; no cookies are set. Visits older than the retention period you choose (365 days by default) are deleted automatically, and you can delete everything or download it at any time. An IP address can be personal data in some countries: if your visitors are protected by such a law, mention the counting in your privacy policy.<\/p>\n\n<p>A visit from a logged-in member also stores that member's user id; the name and e-mail address are read from the WordPress user when you open the details. Words typed into the search box of your website (<code>?s=<\/code>) are stored with the visit. Visitor Stats never reads or stores a computer name, a file path or an e-mail address from the visitor's device: browsers do not allow websites to read them.<\/p>\n\n<p>The country is read from your CDN or server first (Cloudflare, ArvanCloud, CloudFront and others) and from earlier visits of the same address. The option \"Find the country online when the server does not know it\" is <strong>off by default<\/strong>. Only when you switch it on, and only when the country cannot be read in another way, the visitor IP address is sent to an outside lookup service. See the section \"External services\" below for what is sent, to whom, and the terms and privacy policy of each service. Without that option no address leaves your server. Nothing else is sent to outside services.<\/p>\n\n<p>The toolkit adds suggested text to the privacy policy guide (Settings &gt; Privacy), and connects Visitor Stats to the WordPress tools Tools &gt; Export Personal Data and Tools &gt; Erase Personal Data: visits of a member are found by e-mail address. When a user account is deleted, the visits of that user stay as anonymous statistics.<\/p>\n\n<p>The Contact tab sends nothing from your website; it only opens the e-mail program of the person who presses a button.<\/p>\n\n<p><strong>\u0641\u0627\u0631\u0633\u06cc<\/strong><\/p>\n\n<p>\u0627\u0641\u0632\u0648\u0646\u0647 \u0686\u0646\u062f\u0645\u0646\u0638\u0648\u0631\u0647\u060c \u0645\u0627\u0698\u0648\u0644\u0627\u0631 \u0648 \u0642\u0627\u0628\u0644 \u062a\u0648\u0633\u0639\u0647 \u0628\u0631\u0627\u06cc \u0648\u0631\u062f\u067e\u0631\u0633. \u0622\u0645\u0627\u0631 \u06a9\u0627\u0645\u0644 \u0628\u0627\u0632\u062f\u06cc\u062f \u0648\u0628\u200c\u0633\u0627\u06cc\u062a (\u0686\u0646\u062f \u0628\u0627\u0632\u062f\u06cc\u062f\u060c \u0627\u0632 \u06a9\u062c\u0627\u060c \u0628\u0627 \u0686\u0647 \u0622\u062f\u0631\u0633 IP \u0648 \u0627\u0632 \u06a9\u062f\u0627\u0645 \u06a9\u0634\u0648\u0631\u060c \u0628\u0627 \u0686\u0647 \u062f\u0633\u062a\u06af\u0627\u0647 \u0648 \u0686\u0647 \u0645\u062f\u0644\u06cc)\u060c \u06a9\u0648\u062a\u0627\u0647\u200c\u06a9\u0646\u0646\u062f\u0647\u200c\u06cc \u0644\u06cc\u0646\u06a9 \u0628\u0627 \u062f\u0627\u0645\u0646\u0647\u200c\u06cc \u062e\u0648\u062f\u062a\u0627\u0646\u060c \u0633\u0627\u062e\u062a \u06a9\u06cc\u0648 \u0622\u0631 \u06a9\u062f \u0628\u0631\u0627\u06cc \u0644\u06cc\u0646\u06a9 \u0648 \u0645\u062a\u0646\u060c \u0645\u062d\u0627\u0641\u0638 \u0635\u0641\u062d\u0647 \u0628\u0627 \u062a\u0628 \u0648 \u06a9\u0644\u06cc\u062f \u0631\u0648\u0634\u0646\/\u062e\u0627\u0645\u0648\u0634 \u062c\u062f\u0627\u06af\u0627\u0646\u0647\u060c \u062a\u06a9\u062b\u06cc\u0631 \u0646\u0648\u0634\u062a\u0647 \u0648 \u0628\u0631\u06af\u0647 \u0628\u0627 \u06cc\u06a9 \u06a9\u0644\u06cc\u06a9 \u0648 \u00ab\u0648\u06cc\u0631\u0627\u06cc\u0634 \u0627\u0645\u0646\u00bb \u0635\u0641\u062d\u0647\u200c\u0647\u0627\u06cc \u0632\u0646\u062f\u0647 \u0627\u0632 \u0631\u0627\u0647 \u067e\u06cc\u0634\u200c\u0646\u0648\u06cc\u0633 \u067e\u0646\u0647\u0627\u0646\u060c \u0622\u067e\u0644\u0648\u062f \u0645\u0633\u062a\u0642\u06cc\u0645 \u062a\u0635\u0648\u06cc\u0631 \u067e\u0631\u0648\u0641\u0627\u06cc\u0644 \u0628\u062f\u0648\u0646 \u06af\u0631\u0627\u0648\u0627\u062a\u0627\u0631\u060c \u0648 \u0631\u0627\u0628\u0637 \u0641\u0627\u0631\u0633\u06cc\/\u0627\u0646\u06af\u0644\u06cc\u0633\u06cc \u06a9\u0647 \u0627\u0632 \u062a\u0646\u0638\u06cc\u0645\u0627\u062a \u062e\u0648\u062f \u0627\u0641\u0632\u0648\u0646\u0647 \u0639\u0648\u0636 \u0645\u06cc\u200c\u0634\u0648\u062f.<\/p>\n\n<h3>External services<\/h3>\n\n<p>Bani Honar Toolkit can connect to <strong>one kind of outside service, and only if you switch it on<\/strong>: an IP-address-to-country lookup used by the Visitor Stats module. The Link Shortener, QR Code Generator, Post Duplicator, Page Shield and Profile Pictures modules never contact an outside service: QR codes are drawn in the browser and profile pictures are stored on your own site.<\/p>\n\n<p><strong>IP-address-to-country lookup (Visitor Stats, optional, off by default)<\/strong><\/p>\n\n<ul>\n<li>What it is and what it is for: a free web service that tells which country an IP address belongs to. It is used only to fill in the country of a visit when your CDN or server did not provide it and the address was not already known from an earlier visit.<\/li>\n<li>When it runs: only after an administrator ticks \"Find the country online when the server does not know it\" under Bani Honar Toolkit &gt; Visitor Stats &gt; Settings. Then one request is made for a visit from a public IP address whose country is unknown, and an hourly background task retries up to 20 recent addresses whose country is still unknown. If a service fails, lookups pause for ten minutes.<\/li>\n<li>What is sent: the visitor's IP address (inside the request address) and the plugin name and version in the User-Agent header, for example <code>BaniHonarToolkit\/1.0.0<\/code>. Like any web request, the service also sees your server's IP address. No page address, cookie, name, e-mail or other visitor detail is sent. If you also tick \"Hide the last part of every IP address\", your site saves only the shortened address, but the full address is still used for that single lookup and is not stored.<\/li>\n<li>What comes back: a two-letter country code, which is saved with the visit.<\/li>\n<li>Which service: you choose it in the settings. \"Automatic\" tries ipwho.is first and then GeoJS.<\/li>\n<\/ul>\n\n<p>Services used:<\/p>\n\n<ul>\n<li>ipwho.is (free endpoint of the IPWhois API, <code>https:\/\/ipwho.is\/{ip}<\/code>): <a href=\"https:\/\/ipwhois.io\/terms\">Terms of Service<\/a> and <a href=\"https:\/\/ipwhois.io\/privacy\">Privacy Policy<\/a>.<\/li>\n<li>GeoJS (<code>https:\/\/get.geojs.io\/v1\/ip\/country\/{ip}.json<\/code>): <a href=\"https:\/\/www.geojs.io\/tos\/\">Terms of Service<\/a> and <a href=\"https:\/\/www.geojs.io\/privacy\/\">Privacy Policy<\/a>.<\/li>\n<\/ul>\n\n<p>If you do not want any address to leave your server, leave the option off, or answer from a local database with the <code>bhtk_geo_lookup<\/code> filter, which skips the online services. If you use the option, mention it in your own privacy policy; the plugin adds suggested text to Settings &gt; Privacy.<\/p>\n\n<p>Links that open another website only when you click them (for example \"Write in Gmail\" on the Contact us tab, or the Google Search Console link in Visitor Stats) are ordinary links; the plugin itself sends nothing to those sites.<\/p>\n\n<!--section=installation-->\n<ol>\n<li>In WordPress open Plugins &gt; Add New &gt; Upload Plugin, choose the zip file and press Install Now. (Or upload the <code>bani-honar-toolkit<\/code> folder to <code>\/wp-content\/plugins\/<\/code>.)<\/li>\n<li>Activate the plugin. If an older version is installed, WordPress offers to replace it; your data is kept.<\/li>\n<li>Open <strong>Bani Honar Toolkit<\/strong> in the admin menu. Switch modules on or off on the Dashboard (Page Shield, Visitor Stats and Post Duplicator also have a switch on their own tab) and choose the language under Settings.<\/li>\n<\/ol>\n\n<p>For the shortest links, use any permalink structure other than \"Plain\" in Settings &gt; Permalinks.<\/p>\n\n<!--section=faq-->\n<dl>\n<dt id=\"is%20%22edit%20safely%22%20different%20from%20just%20editing%20a%20live%20page%3F\"><h3>Is \"Edit safely\" different from just editing a live page?<\/h3><\/dt>\n<dd><p>Yes. The page is copied to a hidden draft. You edit the draft with the normal editor (Elementor too) while visitors keep seeing the live page. When you press \"Publish into the live page\", the draft replaces the text and fields of the live page, which keeps its address, id, date and comments, and the old text is saved as a revision you can restore. Draft and live page are linked, so a second draft cannot be started for the same page.<\/p><\/dd>\n<dt id=\"what%20if%20somebody%20changes%20the%20live%20page%20while%20i%20edit%20the%20draft%3F\"><h3>What if somebody changes the live page while I edit the draft?<\/h3><\/dt>\n<dd><p>The plugin notices. When you publish, it tells you that the live page changed after the draft was made, and you can choose \"Publish anyway\" or go back and compare first.<\/p><\/dd>\n<dt id=\"why%20can%20i%20not%20duplicate%20woocommerce%20products%3F\"><h3>Why can I not duplicate WooCommerce products?<\/h3><\/dt>\n<dd><p>Products, variations and orders keep prices, stock and relations in extra database tables that a general copier cannot copy correctly. Use the duplicate button that WooCommerce provides.<\/p><\/dd>\n<dt id=\"can%20page%20shield%20make%20my%20pages%20impossible%20to%20copy%3F\"><h3>Can Page Shield make my pages impossible to copy?<\/h3><\/dt>\n<dd><p>No. Nothing can. A browser must receive the HTML, CSS and JavaScript of a page, so a determined person can always read them. Page Shield only stops casual copying. PHP code stays on the server and is never visible.<\/p><\/dd>\n<dt id=\"does%20page%20shield%20hurt%20seo%3F\"><h3>Does Page Shield hurt SEO?<\/h3><\/dt>\n<dd><p>No. Its options (right-click menu, developer shortcuts, image dragging, hidden WordPress version details) do not change the content that search engines read. Options that could hurt your ranking are deliberately not offered.<\/p><\/dd>\n<dt id=\"how%20do%20i%20send%20a%20suggestion%2C%20a%20criticism%20or%20a%20problem%20report%2C%20or%20ask%20for%20a%20module%3F\"><h3>How do I send a suggestion, a criticism or a problem report, or ask for a module?<\/h3><\/dt>\n<dd><p>Open the Contact tab of the toolkit and press a button on the card you need: \"Write in Gmail\" opens a new message in Gmail, \"Mail app\" opens the e-mail program of your computer, and \"Copy message\" copies the whole text so you can send it from any e-mail service to it@banihonarpars.ir. Nothing is sent by your website.<\/p><\/dd>\n<dt id=\"i%20found%20a%20security%20problem.%20who%20do%20i%20tell%3F\"><h3>I found a security problem. Who do I tell?<\/h3><\/dt>\n<dd><p>Please do not post it in public. Use \"Report a security problem\" on the Contact tab, or write to it@banihonarpars.ir. See SECURITY.md in the GitHub repository.<\/p><\/dd>\n<dt id=\"can%20i%20see%20the%20real%20ip%20address%20behind%20a%20proxy%20or%20cdn%3F\"><h3>Can I see the real IP address behind a proxy or CDN?<\/h3><\/dt>\n<dd><p>By default the plugin reads the visitor address from the headers a CDN adds (Cloudflare, ArvanCloud and others) and falls back to the connection address. If your site can also be reached directly, without the CDN, a visitor can send a forged header, so the statistics of that visitor can be wrong. For a site that is not behind a CDN, choose \"Only the direct connection (cannot be faked)\" in Visitor Stats &gt; Settings. Blocking checks both the header address and the connection address, so a forged header cannot be used to avoid a block.<\/p><\/dd>\n<dt id=\"why%20do%20i%20not%20see%20my%20own%20visits%20in%20visitor%20stats%3F\"><h3>Why do I not see my own visits in Visitor Stats?<\/h3><\/dt>\n<dd><p>Visits of logged-in administrators are not counted, so your own work does not change the numbers. Open your website in a private window or on your phone to test. You can change this under Visitor Stats &gt; Settings.<\/p><\/dd>\n<dt id=\"does%20visitor%20stats%20work%20with%20caching%20plugins%3F\"><h3>Does Visitor Stats work with caching plugins?<\/h3><\/dt>\n<dd><p>Yes. The visit is sent by a small script after the page has loaded, so it is counted even when the page comes from a cache. If a visit never shows up, check that a security or cache plugin is not blocking <code>admin-ajax.php<\/code> for visitors.<\/p><\/dd>\n<dt id=\"how%20is%20the%20country%20found%3F\"><h3>How is the country found?<\/h3><\/dt>\n<dd><p>From your CDN or server first (Cloudflare, ArvanCloud and others add the country to every request), then from earlier visits of the same IP address, and finally, only if \"Find the country online\" is switched on (it is off by default), from a free lookup service. See the Privacy section. Developers can plug in their own database with the <code>bhtk_geo_lookup<\/code> filter.<\/p><\/dd>\n<dt id=\"can%20it%20show%20the%20name%20of%20the%20visitor%27s%20computer%20or%20their%20e-mail%20address%3F\"><h3>Can it show the name of the visitor's computer or their e-mail address?<\/h3><\/dt>\n<dd><p>No. Browsers do not let websites read the computer name, folders or e-mail accounts of a visitor, and this plugin does not try. What it can show is the IP address, country, device type, brand and model (when the browser reports it), system, browser, screen size, language, time zone, and the name and e-mail of a visitor who is logged in to your website.<\/p><\/dd>\n<dt id=\"can%20i%20see%20what%20visitors%20searched%20for%20in%20google%3F\"><h3>Can I see what visitors searched for in Google?<\/h3><\/dt>\n<dd><p>No website can: Google no longer passes the search words to the sites it sends visitors to. Use Google Search Console (free) for that. Visitor Stats shows the words typed into the search box of your own website.<\/p><\/dd>\n<dt id=\"can%20i%20block%20a%20troublemaker%3F\"><h3>Can I block a troublemaker?<\/h3><\/dt>\n<dd><p>Yes. Open the visit log, press Details on a visit, then \"Block this IP address\", or use the Blocked IPs tab. Remember that an IP address belongs to a network connection, not one device: people on the same Wi-Fi, and many mobile users, share an address. Prefer a temporary block. Blocking works for requests that reach WordPress; a page that a CDN or cache serves directly is not stopped. If you lock yourself out, add <code>define( 'BHTK_NO_IP_BLOCK', true );<\/code> to wp-config.php.<\/p><\/dd>\n<dt id=\"can%20it%20show%20the%20exact%20model%20of%20every%20phone%3F\"><h3>Can it show the exact model of every phone?<\/h3><\/dt>\n<dd><p>Android phones in Chrome report their model, for example Samsung Galaxy A54 5G. Apple does not let websites read the iPhone model, so only the family (for example \"Apple iPhone 12 \/ 13 \/ 14\") is shown, and some Android browsers hide the model as well.<\/p><\/dd>\n<dt id=\"what%20happens%20to%20my%20visits%20if%20i%20switch%20visitor%20stats%20off%3F\"><h3>What happens to my visits if I switch Visitor Stats off?<\/h3><\/dt>\n<dd><p>Counting stops, and the saved visits stay visible on its tab until you delete them. Deactivating the plugin never deletes data.<\/p><\/dd>\n<dt id=\"does%20the%20qr%20code%20generator%20send%20my%20text%20to%20another%20website%3F\"><h3>Does the QR code generator send my text to another website?<\/h3><\/dt>\n<dd><p>No. The code is drawn in your browser by a bundled script. Nothing is uploaded and nothing is stored.<\/p><\/dd>\n<dt id=\"do%20short%20links%20work%20with%20%22plain%22%20permalinks%3F\"><h3>Do short links work with \"Plain\" permalinks?<\/h3><\/dt>\n<dd><p>Yes, but they look like <code>example.com\/?bhtk=Ab33<\/code>. Choose another permalink structure for links like <code>example.com\/Ab33<\/code>.<\/p><\/dd>\n<dt id=\"can%20a%20short%20link%20replace%20one%20of%20my%20pages%3F\"><h3>Can a short link replace one of my pages?<\/h3><\/dt>\n<dd><p>No. A short link is used only when WordPress would otherwise show a \"not found\" page. When you create a custom code, the plugin also refuses codes that match an existing page or post.<\/p><\/dd>\n<dt id=\"are%20%22ab%22%20and%20%22ab%22%20the%20same%20link%3F\"><h3>Are \"Ab\" and \"ab\" the same link?<\/h3><\/dt>\n<dd><p>No. Codes are case-sensitive.<\/p><\/dd>\n<dt id=\"can%20i%20change%20the%20language%20of%20the%20plugin%20without%20changing%20my%20site%20language%3F\"><h3>Can I change the language of the plugin without changing my site language?<\/h3><\/dt>\n<dd><p>Yes. Go to Bani Honar Toolkit &gt; Settings &gt; Plugin language and choose Persian or English.<\/p><\/dd>\n<dt id=\"where%20does%20the%20persian%20translation%20come%20from%3F\"><h3>Where does the Persian translation come from?<\/h3><\/dt>\n<dd><p>From the language pack that WordPress delivers from translate.wordpress.org, or from a Persian file in the plugin's <code>languages<\/code> folder when the plugin was installed from a package that includes it. If the Persian screens do not appear, copy <code>bani-honar-toolkit-fa_IR.mo<\/code> into <code>wp-content\/languages\/plugins\/<\/code>; it survives plugin updates.<\/p><\/dd>\n<dt id=\"what%20happens%20to%20my%20data%20when%20i%20delete%20the%20plugin%3F\"><h3>What happens to my data when I delete the plugin?<\/h3><\/dt>\n<dd><p>Nothing, unless you tick \"Delete all toolkit data when the plugin is deleted\" in Settings first.<\/p><\/dd>\n<dt id=\"i%20used%20the%20older%20%22bhac%22%20plugin.\"><h3>I used the older \"BHAC\" plugin.<\/h3><\/dt>\n<dd><p>Your links and settings are copied automatically the first time Bani Honar Toolkit is activated. The old plugin is left untouched; deactivate it afterwards. Profile pictures uploaded with the old plugin keep working.<\/p><\/dd>\n\n<\/dl>\n\n<!--section=changelog-->\n<h4>1.0.0<\/h4>\n\n<p>First public release. Before this release the toolkit went through many rounds of testing and changes while it was used inside the agency, and everything that was built and tested in that time is part of 1.0.0:<\/p>\n\n<ul>\n<li>Link Shortener: short links on your own domain with random or custom case-sensitive codes, click counter, redirect type, optional path prefix, search, edit and delete. A short link never hides a real page.<\/li>\n<li>QR Code Generator: PNG and SVG download, colors, size and error correction, Persian text, drawn in the browser.<\/li>\n<li>Visitor Stats (off by default): overview with chart, sources (search engines, social networks, messengers, campaigns), countries, devices with brand and model, systems and browsers, visit log with filters, details and CSV download, website search words, logged-in members, Jalali or Gregorian dates, retention period, IP exclusion list, and blocking of IP addresses and IPv4 ranges (temporary or permanent, with protection against blocking yourself).<\/li>\n<li>Post Duplicator: duplicate posts, pages and custom content from the lists, the bulk actions menu, the admin bar and the editor, with a title pattern and copy options, and \"Edit safely\" - edit a live page through a hidden draft and publish it into the live page with one click (revision saved, conflict warning, address and comments kept). Elementor and block data are copied byte for byte.<\/li>\n<li>Page Shield (off by default): blocked right-click menu, developer shortcuts and image dragging, and hidden WordPress version details. Every option is off until you tick it, and none of them affects search engines; options that could lower the search ranking are deliberately not offered.<\/li>\n<li>Profile Pictures: upload a profile picture from the profile screen, no Gravatar needed. Pictures are checked and saved again as small squares.<\/li>\n<li>Contact tab: suggestions, criticism, problem reports, security reports and module requests for the IT team (it@banihonarpars.ir). Each card opens Gmail or your mail program with a ready text, and can copy the whole message; nothing is sent from your website.<\/li>\n<li>Persian (RTL) and English (LTR) screens with a language switch in the plugin settings, and a complete Persian translation.<\/li>\n<li>Privacy: the online country lookup is off by default, suggested privacy policy text, support for WordPress \"Export Personal Data\" and \"Erase Personal Data\", and anonymous statistics when a user is deleted.<\/li>\n<li>Security review: every action checks permission and nonce, database queries are prepared, all output is escaped, CSV files are protected against spreadsheet formulas, short links accept only http and https, uploaded pictures are re-saved. Two findings were fixed: blocking can no longer be avoided with a forged proxy header, and the visit counter has a per-minute ceiling against floods.<\/li>\n<li>Tested again and again: about 430 automated checks, which were repeated after every change, on a test stand-in for WordPress. Please test the plugin on your own site before using it in production.<\/li>\n<li>Migration: links and settings of the older \"BHAC\" plugin are copied automatically the first time the toolkit is activated.<\/li>\n<\/ul>","raw_excerpt":"Visitor statistics, link shortener, QR codes, post duplicator with safe editing and page shield in one modular plugin. Persian and English.","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin\/398813","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin"}],"about":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/types\/plugin"}],"replies":[{"embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/comments?post=398813"}],"author":[{"embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wporg\/v1\/users\/banihonar"}],"wp:attachment":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/media?parent=398813"}],"wp:term":[{"taxonomy":"plugin_section","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_section?post=398813"},{"taxonomy":"plugin_tags","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_tags?post=398813"},{"taxonomy":"plugin_category","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_category?post=398813"},{"taxonomy":"plugin_contributors","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_contributors?post=398813"},{"taxonomy":"plugin_business_model","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_business_model?post=398813"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}