├── .bowerrc ├── .eslintignore ├── .eslintrc ├── .gitattributes ├── .gitignore ├── README.md ├── bower.json ├── build.xml ├── composer.json ├── composer.lock ├── gulpfile.js ├── package-lock.json ├── package.json └── src ├── LICENSE.txt ├── changelog.txt ├── classes ├── helper.class.php └── stcr_i18n.php ├── images ├── delete.png ├── donate.gif ├── edit.png ├── rate.png ├── stcr-logo-150.png ├── stcr-logo.png ├── subscribe-to-comments-small.png └── subscribe-to-comments.png ├── includes ├── css │ ├── font-awesome.css │ ├── font-awesome.min.css │ ├── fontawesome-all.css │ ├── fontawesome-all.min.css │ ├── stcr-admin-style.css │ ├── stcr-plugin-style.css │ └── stcr-style.css ├── fonts │ ├── FontAwesome.otf │ ├── fontawesome-webfont.eot │ ├── fontawesome-webfont.svg │ ├── fontawesome-webfont.ttf │ ├── fontawesome-webfont.woff │ └── fontawesome-webfont.woff2 ├── js │ ├── admin │ │ ├── management_page.js │ │ ├── stcr_system.js │ │ ├── subs_management.js │ │ └── subs_options.js │ ├── stcr-admin.js │ ├── stcr-plugin.js │ └── stcr-tinyMCE.js ├── sass │ ├── _buttons.scss │ ├── _cards.scss │ ├── _forms.scss │ ├── _init.scss │ ├── _interactions.scss │ ├── _spinners.scss │ ├── _tables.scss │ ├── _utils.scss │ ├── stcr-admin-style.scss │ └── stcr-style.scss └── webfonts │ ├── fa-brands-400.eot │ ├── fa-brands-400.svg │ ├── fa-brands-400.ttf │ ├── fa-brands-400.woff │ ├── fa-brands-400.woff2 │ ├── fa-regular-400.eot │ ├── fa-regular-400.svg │ ├── fa-regular-400.ttf │ ├── fa-regular-400.woff │ ├── fa-regular-400.woff2 │ ├── fa-solid-900.eot │ ├── fa-solid-900.svg │ ├── fa-solid-900.ttf │ ├── fa-solid-900.woff │ └── fa-solid-900.woff2 ├── langs ├── subscribe-to-comments-reloaded-ar.mo ├── subscribe-to-comments-reloaded-ar_AE.po ├── subscribe-to-comments-reloaded-be_BY.mo ├── subscribe-to-comments-reloaded-be_BY.po ├── subscribe-to-comments-reloaded-cs_CZ.mo ├── subscribe-to-comments-reloaded-cs_CZ.po ├── subscribe-to-comments-reloaded-da_DK.mo ├── subscribe-to-comments-reloaded-da_DK.po ├── subscribe-to-comments-reloaded-es_ES.mo ├── subscribe-to-comments-reloaded-es_ES.po ├── subscribe-to-comments-reloaded-fa_IR.mo ├── subscribe-to-comments-reloaded-fa_IR.po ├── subscribe-to-comments-reloaded-fr_FR.mo ├── subscribe-to-comments-reloaded-fr_FR.po ├── subscribe-to-comments-reloaded-he_IL.mo ├── subscribe-to-comments-reloaded-he_IL.po ├── subscribe-to-comments-reloaded-hu_HU.mo ├── subscribe-to-comments-reloaded-hu_HU.po ├── subscribe-to-comments-reloaded-id_ID.mo ├── subscribe-to-comments-reloaded-id_ID.po ├── subscribe-to-comments-reloaded-it_IT.mo ├── subscribe-to-comments-reloaded-it_IT.po ├── subscribe-to-comments-reloaded-nb_NO.mo ├── subscribe-to-comments-reloaded-nb_NO.po ├── subscribe-to-comments-reloaded-nl_NL.mo ├── subscribe-to-comments-reloaded-nl_NL.po ├── subscribe-to-comments-reloaded-pl_PL.mo ├── subscribe-to-comments-reloaded-pl_PL.po ├── subscribe-to-comments-reloaded-pt_BR.mo ├── subscribe-to-comments-reloaded-pt_BR.po ├── subscribe-to-comments-reloaded-pt_PT.mo ├── subscribe-to-comments-reloaded-pt_PT.po ├── subscribe-to-comments-reloaded-sr_RS.mo ├── subscribe-to-comments-reloaded-sr_RS.po ├── subscribe-to-comments-reloaded-sv_SE.mo ├── subscribe-to-comments-reloaded-sv_SE.po ├── subscribe-to-comments-reloaded-tr_TR.mo ├── subscribe-to-comments-reloaded-tr_TR.po ├── subscribe-to-comments-reloaded-zh_CN.mo ├── subscribe-to-comments-reloaded-zh_CN.po └── subscribe-to-comments-reloaded.pot ├── options ├── index.php ├── options_template.php ├── panel1-add-subscription.php ├── panel1-business-logic.php ├── panel1-edit-subscription.php ├── stcr_comment_form.php ├── stcr_manage_subscriptions.php ├── stcr_management_page.php ├── stcr_notifications.php ├── stcr_options.php ├── stcr_support.php └── stcr_system.php ├── post-and-comments.css ├── readme.txt ├── style.css ├── subscribe-to-comments-reloaded.php ├── templates ├── author.php ├── confirm.php ├── key_expired.php ├── not-allowed.php ├── one-click-unsubscribe.php ├── request-management-link.php ├── subscribe.php ├── user.php └── wrong-request.php ├── uninstall.php ├── utils ├── functions.php ├── stcr_manage.php ├── stcr_upgrade.php └── stcr_utils.php ├── wp_subscribe_reloaded.php └── wpml-config.xml /.bowerrc: -------------------------------------------------------------------------------- 1 | { 2 | "directory": "src/bower_components/" 3 | } -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | # node modules 2 | node_modules/* 3 | 4 | # bower modules 5 | src/bower_modules/* 6 | 7 | src/vendor/* 8 | 9 | src/includes/tinymce-lite/* -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | // "extends": "wordpress" 3 | "rules":{ 4 | // "camelcase": 1, 5 | "comma-dangle": 2, 6 | "quotes": 0 7 | } 8 | } -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ################# 2 | ## Eclipse 3 | ################# 4 | 5 | *.pydevproject 6 | .project 7 | .metadata 8 | bin/ 9 | tmp/ 10 | *.tmp 11 | *.bak 12 | *.swp 13 | *~.nib 14 | local.properties 15 | .classpath 16 | .settings/ 17 | .loadpath 18 | 19 | # External tool builders 20 | .externalToolBuilders/ 21 | 22 | # Locally stored "Eclipse launch configurations" 23 | *.launch 24 | 25 | # CDT-specific 26 | .cproject 27 | 28 | # PDT-specific 29 | .buildpath 30 | 31 | 32 | ################# 33 | ## Visual Studio 34 | ################# 35 | 36 | ## Ignore Visual Studio temporary files, build results, and 37 | ## files generated by popular Visual Studio add-ons. 38 | 39 | # User-specific files 40 | *.suo 41 | *.user 42 | *.sln.docstates 43 | 44 | # Build results 45 | [Dd]ebug/ 46 | [Rr]elease/ 47 | *_i.c 48 | *_p.c 49 | *.ilk 50 | *.meta 51 | *.obj 52 | *.pch 53 | *.pdb 54 | *.pgc 55 | *.pgd 56 | *.rsp 57 | *.sbr 58 | *.tlb 59 | *.tli 60 | *.tlh 61 | *.tmp 62 | *.vspscc 63 | .builds 64 | *.dotCover 65 | 66 | ## TODO: If you have NuGet Package Restore enabled, uncomment this 67 | #packages/ 68 | 69 | # Visual C++ cache files 70 | ipch/ 71 | *.aps 72 | *.ncb 73 | *.opensdf 74 | *.sdf 75 | 76 | # Visual Studio profiler 77 | *.psess 78 | *.vsp 79 | 80 | # ReSharper is a .NET coding add-in 81 | _ReSharper* 82 | 83 | # Installshield output folder 84 | [Ee]xpress 85 | 86 | # DocProject is a documentation generator add-in 87 | DocProject/buildhelp/ 88 | DocProject/Help/*.HxT 89 | DocProject/Help/*.HxC 90 | DocProject/Help/*.hhc 91 | DocProject/Help/*.hhk 92 | DocProject/Help/*.hhp 93 | DocProject/Help/Html2 94 | DocProject/Help/html 95 | 96 | # Click-Once directory 97 | publish 98 | 99 | # Others 100 | [Bb]in 101 | [Oo]bj 102 | sql 103 | TestResults 104 | *.Cache 105 | ClientBin 106 | stylecop.* 107 | ~$* 108 | *.dbmdl 109 | Generated_Code #added for RIA/Silverlight projects 110 | 111 | # Backup & report files from converting an old project file to a newer 112 | # Visual Studio version. Backup files are not needed, because we have git ;-) 113 | _UpgradeReport_Files/ 114 | Backup*/ 115 | UpgradeLog*.XML 116 | 117 | 118 | 119 | ############ 120 | ## Windows 121 | ############ 122 | 123 | # Windows image file caches 124 | Thumbs.db 125 | 126 | # Folder config file 127 | Desktop.ini 128 | 129 | 130 | ############# 131 | ## Python 132 | ############# 133 | 134 | *.py[co] 135 | 136 | # Packages 137 | *.egg 138 | *.egg-info 139 | dist 140 | build 141 | eggs 142 | parts 143 | bin 144 | var 145 | sdist 146 | develop-eggs 147 | .installed.cfg 148 | 149 | # Installer logs 150 | pip-log.txt 151 | 152 | # Unit test / coverage reports 153 | .coverage 154 | .tox 155 | 156 | #Mr Developer 157 | .mr.developer.cfg 158 | 159 | # Mac crap 160 | .DS_Store 161 | .idea 162 | 163 | # Composer vendor directory 164 | src/vendor/ 165 | 166 | # Bower Components 167 | src/bower_components/ 168 | 169 | # Node 170 | node_modules/ 171 | 172 | # Others 173 | src/utils/log.txt 174 | src/utils/systemInformation.txt 175 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Subscribe to Comments Reloaded 2 | ============================== 3 | 4 | Subscribe to Comments Reloaded allows commenters to sign up for e-mail notifications of subsequent replies. 5 | 6 | Download at WordPress.org: http://wordpress.org/plugins/subscribe-to-comments-reloaded/ 7 | 8 | ### Development 9 | 10 | If you would like to contribute to the development I strongly recommend you to pull your code request to the [development branch](https://github.com/stcr/subscribe-to-comments-reloaded/tree/development) instead. The master branch is only a copy of the WordPress version and will only be updated on releases. 11 | 12 | StCR development version now uses **Gulp** and **Composer**. -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "subscribe-to-comments-reloaded", 3 | "private": true, 4 | "dependencies": {}, 5 | "devDependencies": { 6 | "bootstrap": "4.6.1", 7 | "Font-Awesome": "5.0.8", 8 | "datatables": "1.10.16", 9 | "datatables.net-responsive": "2.2.0", 10 | "datatables.net-responsive-bs4": "^2.2.0", 11 | "webui-popover": "^2.1.15" 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /build.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "stcr/subscribe-to-comments-reloaded", 3 | "description": "Subscribe to Comments Reloaded allows commenters to sign up for e-mail notifications of subsequent replies.", 4 | "type": "wordpress-plugin", 5 | "license": "GPL-3.0+", 6 | "authors": [ 7 | { 8 | "name": "reedyseth", 9 | "email": "reedyseth@gmail.com" 10 | } 11 | ], 12 | "config": { 13 | "vendor-dir": "src/vendor", 14 | "preferred-install": "dist" 15 | }, 16 | "require-dev": { 17 | "phing/phing": "2.*" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /composer.lock: -------------------------------------------------------------------------------- 1 | { 2 | "_readme": [ 3 | "This file locks the dependencies of your project to a known state", 4 | "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", 5 | "This file is @generated automatically" 6 | ], 7 | "content-hash": "aa589cd8c08da2955dfc079822149268", 8 | "packages": [], 9 | "packages-dev": [ 10 | { 11 | "name": "phing/phing", 12 | "version": "2.17.2", 13 | "source": { 14 | "type": "git", 15 | "url": "https://github.com/phingofficial/phing.git", 16 | "reference": "8b8cee3eb12c24502fc4c227ac5889746248a140" 17 | }, 18 | "dist": { 19 | "type": "zip", 20 | "url": "https://api.github.com/repos/phingofficial/phing/zipball/8b8cee3eb12c24502fc4c227ac5889746248a140", 21 | "reference": "8b8cee3eb12c24502fc4c227ac5889746248a140", 22 | "shasum": "" 23 | }, 24 | "require": { 25 | "php": ">=5.2.0" 26 | }, 27 | "require-dev": { 28 | "ext-pdo_sqlite": "*", 29 | "mikey179/vfsstream": "^1.6", 30 | "pdepend/pdepend": "2.x", 31 | "pear/archive_tar": "1.4.x", 32 | "pear/http_request2": "dev-trunk", 33 | "pear/net_growl": "dev-trunk", 34 | "pear/pear-core-minimal": "1.10.1", 35 | "pear/versioncontrol_git": "@dev", 36 | "pear/versioncontrol_svn": "~0.5", 37 | "phpdocumentor/phpdocumentor": "2.x", 38 | "phploc/phploc": "~2.0.6", 39 | "phpmd/phpmd": "~2.2", 40 | "phpunit/phpunit": ">=3.7", 41 | "sebastian/git": "~1.0", 42 | "sebastian/phpcpd": "2.x", 43 | "siad007/versioncontrol_hg": "^1.0", 44 | "simpletest/simpletest": "^1.1", 45 | "squizlabs/php_codesniffer": "~2.2", 46 | "symfony/yaml": "^2.8 || ^3.1 || ^4.0" 47 | }, 48 | "suggest": { 49 | "pdepend/pdepend": "PHP version of JDepend", 50 | "pear/archive_tar": "Tar file management class", 51 | "pear/versioncontrol_git": "A library that provides OO interface to handle Git repository", 52 | "pear/versioncontrol_svn": "A simple OO-style interface for Subversion, the free/open-source version control system", 53 | "phpdocumentor/phpdocumentor": "Documentation Generator for PHP", 54 | "phploc/phploc": "A tool for quickly measuring the size of a PHP project", 55 | "phpmd/phpmd": "PHP version of PMD tool", 56 | "phpunit/php-code-coverage": "Library that provides collection, processing, and rendering functionality for PHP code coverage information", 57 | "phpunit/phpunit": "The PHP Unit Testing Framework", 58 | "sebastian/phpcpd": "Copy/Paste Detector (CPD) for PHP code", 59 | "siad007/versioncontrol_hg": "A library for interfacing with Mercurial repositories.", 60 | "tedivm/jshrink": "Javascript Minifier built in PHP" 61 | }, 62 | "bin": [ 63 | "bin/phing" 64 | ], 65 | "type": "library", 66 | "extra": { 67 | "branch-alias": { 68 | "dev-master": "2.16.x-dev" 69 | } 70 | }, 71 | "autoload": { 72 | "classmap": [ 73 | "classes/phing/" 74 | ] 75 | }, 76 | "notification-url": "https://packagist.org/downloads/", 77 | "include-path": [ 78 | "classes" 79 | ], 80 | "license": [ 81 | "LGPL-3.0-only" 82 | ], 83 | "authors": [ 84 | { 85 | "name": "Michiel Rook", 86 | "email": "mrook@php.net" 87 | }, 88 | { 89 | "name": "Phing Community", 90 | "homepage": "https://www.phing.info/trac/wiki/Development/Contributors" 91 | } 92 | ], 93 | "description": "PHing Is Not GNU make; it's a PHP project build system or build tool based on Apache Ant.", 94 | "homepage": "https://www.phing.info/", 95 | "keywords": [ 96 | "build", 97 | "phing", 98 | "task", 99 | "tool" 100 | ], 101 | "support": { 102 | "irc": "irc://irc.freenode.net/phing", 103 | "issues": "https://www.phing.info/trac/report", 104 | "source": "https://github.com/phingofficial/phing/tree/2.17.2" 105 | }, 106 | "funding": [ 107 | { 108 | "url": "https://github.com/mrook", 109 | "type": "github" 110 | }, 111 | { 112 | "url": "https://github.com/siad007", 113 | "type": "github" 114 | }, 115 | { 116 | "url": "https://www.patreon.com/michielrook", 117 | "type": "patreon" 118 | } 119 | ], 120 | "time": "2022-02-09T09:50:58+00:00" 121 | } 122 | ], 123 | "aliases": [], 124 | "minimum-stability": "stable", 125 | "stability-flags": [], 126 | "prefer-stable": false, 127 | "prefer-lowest": false, 128 | "platform": [], 129 | "platform-dev": [], 130 | "plugin-api-version": "2.2.0" 131 | } 132 | -------------------------------------------------------------------------------- /gulpfile.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Gulp Configuration File. 3 | * 4 | * @since 21-March-2018 5 | * @author Reedyseth 6 | * @version 1.0.0 7 | * 8 | * */ 9 | var gulp = require( 'gulp' ); 10 | var eslint = require( 'gulp-eslint' ); 11 | var watch = require('gulp-watch'); 12 | var sass = require('gulp-sass')(require('sass')); 13 | 14 | gulp.task('lint', function() { 15 | // ESLint ignores files with "node_modules" paths. 16 | // So, it's best to have gulp ignore the directory as well. 17 | // Also, Be sure to return the stream from the task; 18 | // Otherwise, the task may end before the stream has finished. 19 | return gulp.src([ 20 | '**/*.js', 21 | '!node_modules/**', 22 | '!src/bower_components/**', 23 | '!src/includes/tinymce-lite/**' 24 | ]) 25 | // eslint() attaches the lint output to the "eslint" property 26 | // of the file object so it can be used by other modules. 27 | .pipe(eslint()) 28 | // eslint.format() outputs the lint results to the console. 29 | // Alternatively use eslint.formatEach() (see Docs). 30 | .pipe(eslint.format()) 31 | // To have the process exit with an error code (1) on 32 | // lint error, return the stream and pipe to failAfterError last. 33 | .pipe(eslint.failAfterError()); 34 | }); 35 | 36 | gulp.task('sass', function () { 37 | return gulp.src('src/includes/sass/*.scss') 38 | .pipe(sass.sync().on( 'error', sass.logError ) ) 39 | .pipe( gulp.dest( 'src/includes/css' ) ); 40 | }); 41 | 42 | gulp.task('watch', function () { 43 | // gulp.watch('src/includes/js/admin/**/*.js', ['lint']); 44 | gulp.watch('src/includes/sass/*.scss', ['sass']); 45 | }); 46 | 47 | gulp.task('copy', function () { 48 | return gulp.src([ 49 | 'src/**/*', 50 | '!src/bower_components/', 51 | '!src/utils/log.txt' 52 | // 'src/**' 53 | ]) 54 | .pipe( gulp.dest('build') ); 55 | }); 56 | 57 | gulp.task('build', function () { 58 | 59 | }); 60 | 61 | gulp.task('compile', function () { 62 | 63 | }); 64 | 65 | gulp.task('default', gulp.series('lint'), function () { 66 | // This will only run if the lint task is successful... 67 | }); 68 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "subscribe-to-comments-reloaded", 3 | "version": "1.0.0", 4 | "description": "Subscribe to Comments Reloaded allows commenters to sign up for e-mail notifications of subsequent replies.", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git+https://github.com/stcr/subscribe-to-comments-reloaded.git" 12 | }, 13 | "keywords": [ 14 | "comments", 15 | "subscribe", 16 | "subscribe", 17 | "to", 18 | "comments", 19 | "subscribe", 20 | "to", 21 | "comments", 22 | "reloaded", 23 | "email", 24 | "email", 25 | "notification", 26 | "subscriptions", 27 | "commenting", 28 | "reply", 29 | "reply", 30 | "to", 31 | "comments", 32 | "post", 33 | "notification", 34 | "comment", 35 | "notification", 36 | "automatic", 37 | "comment", 38 | "notification", 39 | "email", 40 | "signup" 41 | ], 42 | "author": "Reedyseth", 43 | "license": "GPL-3.0", 44 | "bugs": { 45 | "url": "https://github.com/stcr/subscribe-to-comments-reloaded/issues" 46 | }, 47 | "homepage": "https://github.com/stcr/subscribe-to-comments-reloaded#readme", 48 | "devDependencies": { 49 | "babel-eslint": "^10.1.0", 50 | "bower": "^1.8.13", 51 | "eslint-plugin-compat": "^4.0.2", 52 | "gulp": "^4.0.2", 53 | "gulp-eslint": "^6.0.0", 54 | "gulp-sass": "^5.1.0", 55 | "gulp-watch": "^5.0.1" 56 | }, 57 | "dependencies": { 58 | "sass": "^1.49.7" 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/LICENSE.txt: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc. 5 | 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Library General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS 281 | 282 | How to Apply These Terms to Your New Programs 283 | 284 | If you develop a new program, and you want it to be of the greatest 285 | possible use to the public, the best way to achieve this is to make it 286 | free software which everyone can redistribute and change under these terms. 287 | 288 | To do so, attach the following notices to the program. It is safest 289 | to attach them to the start of each source file to most effectively 290 | convey the exclusion of warranty; and each file should have at least 291 | the "copyright" line and a pointer to where the full notice is found. 292 | 293 | 294 | Copyright (C) 295 | 296 | This program is free software; you can redistribute it and/or modify 297 | it under the terms of the GNU General Public License as published by 298 | the Free Software Foundation; either version 2 of the License, or 299 | (at your option) any later version. 300 | 301 | This program is distributed in the hope that it will be useful, 302 | but WITHOUT ANY WARRANTY; without even the implied warranty of 303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 304 | GNU General Public License for more details. 305 | 306 | You should have received a copy of the GNU General Public License 307 | along with this program; if not, write to the Free Software 308 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 309 | 310 | 311 | Also add information on how to contact you by electronic and paper mail. 312 | 313 | If the program is interactive, make it output a short notice like this 314 | when it starts in an interactive mode: 315 | 316 | Gnomovision version 69, Copyright (C) year name of author 317 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 318 | This is free software, and you are welcome to redistribute it 319 | under certain conditions; type `show c' for details. 320 | 321 | The hypothetical commands `show w' and `show c' should show the appropriate 322 | parts of the General Public License. Of course, the commands you use may 323 | be called something other than `show w' and `show c'; they could even be 324 | mouse-clicks or menu items--whatever suits your program. 325 | 326 | You should also get your employer (if you work as a programmer) or your 327 | school, if any, to sign a "copyright disclaimer" for the program, if 328 | necessary. Here is a sample; alter the names: 329 | 330 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 331 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 332 | 333 | , 1 April 1989 334 | Ty Coon, President of Vice 335 | 336 | This General Public License does not permit incorporating your program into 337 | proprietary programs. If your program is a subroutine library, you may 338 | consider it more useful to permit linking proprietary applications with the 339 | library. If this is what you want to do, use the GNU Library General 340 | Public License instead of this License. 341 | -------------------------------------------------------------------------------- /src/classes/helper.class.php: -------------------------------------------------------------------------------- 1 | ||(%3C|%3C/))~'; 27 | $detected = false; 28 | if ( preg_match( $pattern, $value ) ) { 29 | $detected = true; 30 | } 31 | 32 | return $detected; 33 | } 34 | } 35 | 36 | ?> 37 | -------------------------------------------------------------------------------- /src/classes/stcr_i18n.php: -------------------------------------------------------------------------------- 1 | wp_locale = get_locale(); 25 | } 26 | 27 | /** 28 | * Enqueue a script a translated array into a Object Name that will be use in the handle JS file. 29 | * 30 | * @since 28-Mar-2018 31 | * @author reedyseth 32 | * @param string $handle Script handle that will be enqueue 33 | * @param string $object_name Name for the JavaScript object. Passed directly, so it should be qualified JS variable. 34 | * Example: '/[a-zA-Z0-9_]+/'. 35 | * @param string $l10n The data itself. The data can be either a single or multi-dimensional array. 36 | */ 37 | public function stcr_localize_script( $handle, $object_name, $l10n ) { 38 | wp_localize_script( $handle, $object_name, $l10n ); 39 | } 40 | /** 41 | * Create the translation array for the plugin jQuery Datatables. 42 | * 43 | * @since 28-Mar-2018 44 | * @author reedyseth 45 | */ 46 | public function register_js_subs_translation() { 47 | $translation_array = array ( 48 | "decimal" => esc_html__( " ", 'subscribe-to-comments-reloaded' ), 49 | "emptyTable" => esc_html__( "No data available in table", 'subscribe-to-comments-reloaded' ), 50 | "info" => esc_html__( "Showing _START_ to _END_ of _TOTAL_ entries", 'subscribe-to-comments-reloaded' ), 51 | "infoEmpty" => esc_html__( "Showing 0 to 0 of 0 entries", 'subscribe-to-comments-reloaded' ), 52 | "infoFiltered" => esc_html__( "(filtered from _MAX_ total entries)", 'subscribe-to-comments-reloaded' ), 53 | "infoPostFix" => esc_html__( " ", 'subscribe-to-comments-reloaded' ), 54 | "thousands" => esc_html__( ",", 'subscribe-to-comments-reloaded' ), 55 | "lengthMenu" => esc_html__( "Show _MENU_ entries", 'subscribe-to-comments-reloaded' ), 56 | "loadingRecords" => esc_html__( "Loading...", 'subscribe-to-comments-reloaded' ), 57 | "processing" => esc_html__( "Processing...", 'subscribe-to-comments-reloaded' ), 58 | "search" => esc_html__( "Search", 'subscribe-to-comments-reloaded' ), 59 | "zeroRecords" => esc_html__( "No matching records found", 'subscribe-to-comments-reloaded' ), 60 | "paginate" => array( 61 | "first" => esc_html__( "First", 'subscribe-to-comments-reloaded' ), 62 | "last" => esc_html__( "Last", 'subscribe-to-comments-reloaded' ), 63 | "next" => esc_html__( "Next", 'subscribe-to-comments-reloaded' ), 64 | "previous" => esc_html__( "Previous", 'subscribe-to-comments-reloaded' ) 65 | ), 66 | "aria" => array( 67 | "sortAscending" => esc_html__( "activate to sort column ascending", 'subscribe-to-comments-reloaded' ), 68 | "sortDescending"=> esc_html__( "activate to sort column descending", 'subscribe-to-comments-reloaded' ) 69 | ), 70 | "langTextDirection" => $this->get_text_direction() 71 | ); 72 | 73 | $this->set_js_subs_translation( $translation_array ); 74 | } 75 | 76 | /** 77 | * @return mixed 78 | */ 79 | public function get_js_subs_translation() { 80 | return $this->js_subs_translation; 81 | } 82 | 83 | /** 84 | * @param mixed $translation_array 85 | */ 86 | public function set_js_subs_translation( $translation_array ) { 87 | $this->js_subs_translation = array_merge( $this->get_js_subs_translation(), $translation_array ); 88 | } 89 | 90 | /** 91 | * @return null 92 | */ 93 | public function get_wp_locale() { 94 | return $this->wp_locale; 95 | } 96 | 97 | public function get_text_direction() { 98 | 99 | if ( function_exists( 'is_rtl' ) && is_rtl() ) { 100 | $text_direction = "rtl"; 101 | } else { 102 | $text_direction = "ltr"; 103 | } 104 | 105 | return $text_direction; 106 | 107 | } 108 | 109 | /** 110 | * @param null $wp_locale 111 | */ 112 | public function set_wp_locale($wp_locale) { 113 | $this->wp_locale = $wp_locale; 114 | } 115 | 116 | } 117 | -------------------------------------------------------------------------------- /src/images/delete.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stcr/subscribe-to-comments-reloaded/0c1e269712d6cfd4fa938a29149eabc184ea9ae3/src/images/delete.png -------------------------------------------------------------------------------- /src/images/donate.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stcr/subscribe-to-comments-reloaded/0c1e269712d6cfd4fa938a29149eabc184ea9ae3/src/images/donate.gif -------------------------------------------------------------------------------- /src/images/edit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stcr/subscribe-to-comments-reloaded/0c1e269712d6cfd4fa938a29149eabc184ea9ae3/src/images/edit.png -------------------------------------------------------------------------------- /src/images/rate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stcr/subscribe-to-comments-reloaded/0c1e269712d6cfd4fa938a29149eabc184ea9ae3/src/images/rate.png -------------------------------------------------------------------------------- /src/images/stcr-logo-150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stcr/subscribe-to-comments-reloaded/0c1e269712d6cfd4fa938a29149eabc184ea9ae3/src/images/stcr-logo-150.png -------------------------------------------------------------------------------- /src/images/stcr-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stcr/subscribe-to-comments-reloaded/0c1e269712d6cfd4fa938a29149eabc184ea9ae3/src/images/stcr-logo.png -------------------------------------------------------------------------------- /src/images/subscribe-to-comments-small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stcr/subscribe-to-comments-reloaded/0c1e269712d6cfd4fa938a29149eabc184ea9ae3/src/images/subscribe-to-comments-small.png -------------------------------------------------------------------------------- /src/images/subscribe-to-comments.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stcr/subscribe-to-comments-reloaded/0c1e269712d6cfd4fa938a29149eabc184ea9ae3/src/images/subscribe-to-comments.png -------------------------------------------------------------------------------- /src/includes/css/stcr-admin-style.css: -------------------------------------------------------------------------------- 1 | /* 2 | Admin styles for StCR. 3 | 4 | @author reedyseth 5 | @since 21-Sep-2015 6 | */ 7 | .h1, .h2, .h3, .h4, .h5, .h6, h1, h2, h3, h4, h5, h6 { 8 | color: inherit; 9 | } 10 | 11 | /* ---------------------------------------------------------- 12 | Common styles and utilities on pages. 13 | @author Israel Barragan (Reedyseth) 14 | @since 01-Apr-2018 15 | ---------------------------------------------------------- */ 16 | .validate-error-text { 17 | color: #f55252; 18 | font-weight: bold; 19 | } 20 | 21 | .validate-error-field { 22 | border: 1px solid #ff9595 !important; 23 | } 24 | 25 | .stcr-hidden { 26 | position: absolute !important; 27 | top: -9999px !important; 28 | left: -9999px !important; 29 | } 30 | 31 | .clearFix { 32 | clear: both; 33 | } 34 | 35 | .hidden { 36 | display: none; 37 | } 38 | 39 | .float-right { 40 | float: right; 41 | } 42 | 43 | .float-left { 44 | float: left; 45 | } 46 | 47 | .stcr-alert-box { 48 | font-size: 0.85em; 49 | } 50 | 51 | /* ---------------------------------------------------------- 52 | Styles use on the interaction with the user. 53 | @author Israel Barragan (Reedyseth) 54 | @since 01-Apr-2018 55 | ---------------------------------------------------------- */ 56 | .stcr-loading-animation { 57 | display: none; 58 | } 59 | 60 | .dismiss { 61 | background: #00a0d2; 62 | border-color: #0073aa; 63 | -webkit-box-shadow: inset 0 1px 0 rgba(120, 200, 230, 0.5), 0 1px 0 rgba(0, 0, 0, 0.15); 64 | box-shadow: inset 0 1px 0 rgba(120, 200, 230, 0.5), 0 1px 0 rgba(0, 0, 0, 0.15); 65 | color: #fff; 66 | text-decoration: none; 67 | display: inline-block; 68 | text-decoration: none; 69 | font-size: 13px; 70 | line-height: 26px; 71 | height: 28px; 72 | margin: 0 0 0 10px; 73 | padding: 0 10px 1px; 74 | cursor: pointer; 75 | border-width: 1px; 76 | border-style: solid; 77 | -webkit-appearance: none; 78 | -webkit-border-radius: 3px; 79 | border-radius: 3px; 80 | white-space: nowrap; 81 | -webkit-box-sizing: border-box; 82 | -moz-box-sizing: border-box; 83 | box-sizing: border-box; 84 | } 85 | 86 | .dismiss:hover { 87 | background: #0091cd; 88 | border-color: #0073aa; 89 | -webkit-box-shadow: inset 0 1px 0 rgba(120, 200, 230, 0.6); 90 | box-shadow: inset 0 1px 0 rgba(120, 200, 230, 0.6); 91 | color: #fff; 92 | } 93 | 94 | .info-panel { 95 | background-color: #BBBBBB; 96 | padding: 8px; 97 | font-style: italic; 98 | } 99 | 100 | .more-info { 101 | color: #008ec2; 102 | cursor: pointer; 103 | width: 10%; 104 | font-size: 1.4rem; 105 | } 106 | 107 | .stcr-dismiss-notice p { 108 | font-size: 0.8rem !important; 109 | } 110 | .stcr-dismiss-notice h2 { 111 | font-size: 1rem !important; 112 | } 113 | 114 | li { 115 | margin-bottom: 0; 116 | } 117 | 118 | .navbar-expand-lg .navbar-nav .dropdown-menu { 119 | top: 30px; 120 | font-size: 0.9rem; 121 | } 122 | 123 | /* ---------------------------------------------------------- 124 | Styles use on form styles. Helpful to customize Bootstrap behavior. 125 | @author Israel Barragan (Reedyseth) 126 | @since 01-Apr-2018 127 | ---------------------------------------------------------- */ 128 | .form-controls-font { 129 | font-size: 1em !important; 130 | } 131 | 132 | .col-form-label { 133 | font-size: 0.95rem !important; 134 | font-weight: 600 !important; 135 | } 136 | 137 | .subscribers-mass-actions { 138 | margin-top: 20px; 139 | font-size: 0.9rem; 140 | } 141 | 142 | .subscribers-mass-actions select, 143 | .subscribers-mass-actions button, 144 | .subscribers-mass-actions input { 145 | font-size: 0.9rem !important; 146 | } 147 | 148 | .mass-update-subs { 149 | /*height: 100%;*/ 150 | margin-top: 0 !important; 151 | } 152 | 153 | .mass-update-select-status { 154 | width: 70% !important; 155 | display: inline !important; 156 | } 157 | 158 | .new-sub-select-status { 159 | width: 76% !important; 160 | display: inline !important; 161 | } 162 | 163 | .form-control { 164 | height: auto !important; 165 | } 166 | 167 | .form-control-select { 168 | width: 42% !important; 169 | display: inline !important; 170 | font-size: 0.9rem !important; 171 | } 172 | 173 | .form-control-input-3 { 174 | width: 30% !important; 175 | display: inline !important; 176 | font-size: 0.9rem !important; 177 | } 178 | 179 | .form-control-input-4 { 180 | width: 40% !important; 181 | display: inline !important; 182 | font-size: 0.9rem !important; 183 | } 184 | 185 | .form-control-input-5 { 186 | width: 50% !important; 187 | display: inline !important; 188 | font-size: 0.9rem !important; 189 | } 190 | 191 | .form-control-input-6 { 192 | width: 60% !important; 193 | display: inline !important; 194 | font-size: 0.9rem !important; 195 | } 196 | 197 | .form-control-input-7 { 198 | width: 70% !important; 199 | display: inline !important; 200 | font-size: 0.9rem !important; 201 | } 202 | 203 | .form-control-input-8 { 204 | width: 80% !important; 205 | display: inline !important; 206 | font-size: 0.9rem !important; 207 | } 208 | 209 | .form-control-input-9 { 210 | width: 90% !important; 211 | display: inline !important; 212 | font-size: 0.9rem !important; 213 | } 214 | 215 | .add-new-subs { 216 | /*height: 100%;*/ 217 | margin-top: 0 !important; 218 | } 219 | 220 | .mass-update-subs h6, 221 | .add-new-subs h6 { 222 | cursor: pointer; 223 | } 224 | 225 | .subscribe-form-button { 226 | font-size: 0.8rem !important; 227 | } 228 | 229 | .switch { 230 | position: relative; 231 | display: inline-flex; 232 | margin-top: 7px; 233 | height: 26px; 234 | width: 120px; 235 | background: rgba(45, 43, 42, 0.1); 236 | border-radius: 3px; 237 | -webkit-box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.13), 0 1px rgba(255, 255, 255, 0.1); 238 | box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.13), 0 1px rgba(255, 255, 255, 0.1); 239 | } 240 | 241 | .switch-label { 242 | position: relative; 243 | z-index: 2; 244 | float: left; 245 | width: 58px; 246 | line-height: 26px; 247 | font-size: 11px; 248 | color: #949494; 249 | text-align: center; 250 | text-shadow: 0 1px 1px rgba(0, 0, 0, 0.45); 251 | cursor: pointer; 252 | } 253 | 254 | .switch-label:active { 255 | font-weight: bold; 256 | } 257 | 258 | .switch-label-off { 259 | padding-left: 2px; 260 | } 261 | 262 | .switch-label-on { 263 | padding-right: 2px; 264 | } 265 | 266 | .switch-input { 267 | display: none !important; 268 | } 269 | 270 | .switch-input:checked + .switch-label { 271 | font-weight: bold; 272 | color: rgba(0, 0, 0, 0.65); 273 | text-shadow: 0 1px rgba(255, 255, 255, 0.25); 274 | -webkit-transition: 0.15s ease-out; 275 | -moz-transition: 0.15s ease-out; 276 | -o-transition: 0.15s ease-out; 277 | transition: 0.15s ease-out; 278 | } 279 | 280 | .switch-input:checked + .switch-label-on ~ .switch-selection { 281 | /* Note: left: 50% doesn't transition in WebKit */ 282 | left: 60px; 283 | background-image: -webkit-linear-gradient(top, #f3e4f6, #82928f); 284 | background-image: -moz-linear-gradient(top, #f3e4f6, #82928f); 285 | background-image: -o-linear-gradient(top, #f3e4f6, #82928f); 286 | background-image: linear-gradient(to bottom, #f3e4f6, #82928f); 287 | } 288 | 289 | .switch-selection { 290 | display: block; 291 | position: absolute; 292 | z-index: 1; 293 | top: 2px; 294 | left: 2px; 295 | width: 58px; 296 | height: 22px; 297 | background: #65bd63; 298 | border-radius: 3px; 299 | background-image: -webkit-linear-gradient(top, #9dd993, #46d443); 300 | background-image: -moz-linear-gradient(top, #9dd993, #46d443); 301 | background-image: -o-linear-gradient(top, #9dd993, #46d443); 302 | background-image: linear-gradient(to bottom, #9dd993, #46d443); 303 | -webkit-box-shadow: inset 0 1px rgba(255, 255, 255, 0.5), 0 0 2px rgba(0, 0, 0, 0.2); 304 | box-shadow: inset 0 1px rgba(255, 255, 255, 0.5), 0 0 2px rgba(0, 0, 0, 0.2); 305 | -webkit-transition: left 0.15s ease-out; 306 | -moz-transition: left 0.15s ease-out; 307 | -o-transition: left 0.15s ease-out; 308 | transition: left 0.15s ease-out; 309 | } 310 | 311 | .switch-blue .switch-selection { 312 | background: #3aa2d0; 313 | background-image: -webkit-linear-gradient(top, #4fc9ee, #3aa2d0); 314 | background-image: -moz-linear-gradient(top, #4fc9ee, #3aa2d0); 315 | background-image: -o-linear-gradient(top, #4fc9ee, #3aa2d0); 316 | background-image: linear-gradient(to bottom, #4fc9ee, #3aa2d0); 317 | } 318 | 319 | .switch-yellow .switch-selection { 320 | background: #c4bb61; 321 | background-image: -webkit-linear-gradient(top, #e0dd94, #c4bb61); 322 | background-image: -moz-linear-gradient(top, #e0dd94, #c4bb61); 323 | background-image: -o-linear-gradient(top, #e0dd94, #c4bb61); 324 | background-image: linear-gradient(to bottom, #e0dd94, #c4bb61); 325 | } 326 | 327 | .helpDescription { 328 | margin-left: 10px; 329 | display: inline-flex; 330 | color: #008ec2; 331 | font-size: 0.9rem; 332 | cursor: pointer; 333 | } 334 | 335 | .webui-popover-helpDescriptionContent { 336 | font-size: 0.85rem; 337 | } 338 | 339 | .arrow { 340 | left: -8px !important; 341 | } 342 | 343 | .arrow:after { 344 | left: 4px !important; 345 | top: 0px !important; 346 | width: 17px !important; 347 | height: 2px !important; 348 | } 349 | 350 | select.form-control:not([size]):not([multiple]) { 351 | height: calc(2.25rem + 2px) !important; 352 | } 353 | 354 | .input-group-sm > .input-group-append > select.btn:not([size]):not([multiple]), .input-group-sm > .input-group-append > select.input-group-text:not([size]):not([multiple]), .input-group-sm > .input-group-prepend > select.btn:not([size]):not([multiple]), .input-group-sm > .input-group-prepend > select.input-group-text:not([size]):not([multiple]), .input-group-sm > select.form-control:not([size]):not([multiple]), select.form-control-sm:not([size]):not([multiple]) { 355 | height: calc(1.8125rem + 2px) !important; 356 | } 357 | 358 | /* ---------------------------------------------------------- 359 | Styles use on Cards styles. Helpful to customize Bootstrap Cards behavior. 360 | @author Israel Barragan (Reedyseth) 361 | @since 01-Apr-2018 362 | ---------------------------------------------------------- */ 363 | .card { 364 | padding: 0 !important; 365 | border-bottom: 0; 366 | } 367 | 368 | .card-subscribers { 369 | -webkit-box-shadow: 0 0 6px 0 #9E9E9E; 370 | box-shadow: 0 0 6px 0 #9E9E9E; 371 | } 372 | 373 | .card-header { 374 | background-color: #008ec2 !important; 375 | color: #ffffff; 376 | } 377 | 378 | .card-font-size { 379 | font-size: 0.85em; 380 | } 381 | 382 | .original-card-padding { 383 | padding: 1.25rem !important; 384 | } 385 | 386 | .card-no-max-width { 387 | max-width: 100% !important; 388 | } 389 | 390 | /* ---------------------------------------------------------- 391 | Styles use on Table styles. Helpful to customize Bootstrap Tables behavior. 392 | @author Israel Barragan (Reedyseth) 393 | @since 01-Apr-2018 394 | ---------------------------------------------------------- */ 395 | .table { 396 | color: #464646 !important; 397 | } 398 | 399 | table.subscribers-table { 400 | width: 100% !important; 401 | } 402 | 403 | table.subscribers-table thead { 404 | background-color: #b3e0f1; 405 | } 406 | 407 | table.subscribers-table thead th { 408 | line-height: normal; 409 | vertical-align: middle; 410 | padding: 0.55rem; 411 | } 412 | 413 | table.subscribers-table thead th:first-child { 414 | width: 15%; 415 | text-align: center; 416 | } 417 | 418 | table.subscribers-table tbody tr td:first-child { 419 | text-align: center; 420 | } 421 | 422 | table.subscribers-table thead th i { 423 | margin-right: 5px; 424 | font-size: 1rem; 425 | } 426 | 427 | table.subscribers-table thead th span { 428 | vertical-align: text-bottom; 429 | font-size: 0.9rem; 430 | text-transform: uppercase; 431 | } 432 | 433 | @media screen and (max-width: 651px) { 434 | table.dataTable.dtr-inline.collapsed > tbody > tr[role=row] > td:first-child, 435 | table.dataTable.dtr-inline.collapsed > tbody > tr[role=row] > th:first-child { 436 | padding-left: 40px !important; 437 | } 438 | } 439 | @media screen and (max-width: 350px) { 440 | table.dataTable.dtr-inline.collapsed > tbody > tr[role=row] > td:first-child, 441 | table.dataTable.dtr-inline.collapsed > tbody > tr[role=row] > th:first-child { 442 | padding-left: 57px !important; 443 | } 444 | } 445 | /* Override rules from DataTables causing styling issues.*/ 446 | .dataTables_wrapper .dataTables_paginate .paginate_button { 447 | padding: 0 !important; 448 | margin-left: 0 !important; 449 | border: none !important; 450 | border-radius: 0px !important; 451 | } 452 | 453 | .dataTables_wrapper .dataTables_paginate .paginate_button:hover, 454 | .dataTables_wrapper .dataTables_paginate .paginate_button:hover { 455 | background: none !important; 456 | -webkit-box-shadow: none !important; 457 | -moz-box-shadow: none !important; 458 | box-shadow: none !important; 459 | } 460 | 461 | .system-info-table a { 462 | color: #0073aa; 463 | } 464 | 465 | /* ---------------------------------------------------------- 466 | Styles use on form styles. Helpful to customize Bootstrap Buttons behavior. 467 | @author Israel Barragan (Reedyseth) 468 | @since 01-Apr-2018 469 | ---------------------------------------------------------- */ 470 | .btn { 471 | white-space: nowrap; 472 | } 473 | 474 | .btn-primary { 475 | color: #fff !important; 476 | background-color: #0085ba !important; 477 | border-color: #80bbd2 !important; 478 | } 479 | 480 | .btn-primary:hover { 481 | color: #fff !important; 482 | background-color: #4299b9 !important; 483 | border-color: #5495ad !important; 484 | } 485 | 486 | .btn-third { 487 | color: #444 !important; 488 | background-color: #ffc63c !important; 489 | border-color: #dcb456 !important; 490 | } 491 | 492 | .btn-third:hover { 493 | color: #444 !important; 494 | background-color: #fdd575 !important; 495 | border-color: #dcb456 !important; 496 | } 497 | 498 | .btn-download { 499 | color: #445435; 500 | background-color: #7bd774 !important; 501 | border-color: #28a745 !important; 502 | } 503 | 504 | .btn-download:hover { 505 | color: #445435; 506 | background-color: #78c771 !important; 507 | border-color: #28a745 !important; 508 | } 509 | 510 | /* ---------------------------------------------------------- 511 | Styles use on loading events. 512 | @author Israel Barragan (Reedyseth) 513 | @since 01-Apr-2018 514 | ---------------------------------------------------------- */ 515 | .fa-spinner, .fa-play-circle { 516 | color: #ffc53a; 517 | -webkit-animation-name: spin; 518 | -webkit-animation-duration: 900ms; 519 | -webkit-animation-iteration-count: infinite; 520 | -webkit-animation-timing-function: cubic-bezier(0.4, 0.62, 0.93, 0.98); 521 | -moz-animation-name: spin; 522 | -moz-animation-duration: 900ms; 523 | -moz-animation-iteration-count: infinite; 524 | -moz-animation-timing-function: cubic-bezier(0.4, 0.62, 0.93, 0.98); 525 | -ms-animation-name: spin; 526 | -ms-animation-duration: 900ms; 527 | -ms-animation-iteration-count: infinite; 528 | -ms-animation-timing-function: cubic-bezier(0.4, 0.62, 0.93, 0.98); 529 | animation-name: spin; 530 | animation-duration: 900ms; 531 | animation-iteration-count: infinite; 532 | animation-timing-function: cubic-bezier(0.4, 0.62, 0.93, 0.98); 533 | } 534 | 535 | @-ms-keyframes spin { 536 | from { 537 | -ms-transform: rotate(0deg); 538 | } 539 | to { 540 | -ms-transform: rotate(360deg); 541 | } 542 | } 543 | @-moz-keyframes spin { 544 | from { 545 | -moz-transform: rotate(0deg); 546 | } 547 | to { 548 | -moz-transform: rotate(360deg); 549 | } 550 | } 551 | @-webkit-keyframes spin { 552 | from { 553 | -webkit-transform: rotate(0deg); 554 | } 555 | to { 556 | -webkit-transform: rotate(360deg); 557 | } 558 | } 559 | @keyframes spin { 560 | from { 561 | transform: rotate(0deg); 562 | } 563 | to { 564 | transform: rotate(360deg); 565 | } 566 | } -------------------------------------------------------------------------------- /src/includes/css/stcr-plugin-style.css: -------------------------------------------------------------------------------- 1 | /** 2 | * Styles for the StCR plugin 3 | * @since 23-Sep-2015 4 | * @author reedyseth 5 | */ 6 | 7 | .stcr-hidden { 8 | display: none !important; 9 | } -------------------------------------------------------------------------------- /src/includes/css/stcr-style.css: -------------------------------------------------------------------------------- 1 | .stcr-pagination-links { 2 | display: flex; 3 | flex-wrap: wrap; 4 | } 5 | .stcr-pagination-links .stcr-page-link { 6 | display: block; 7 | padding: 5px 15px; 8 | margin-left: -1px; 9 | border: 1px solid #eaeaea; 10 | } 11 | .stcr-pagination-links .stcr-page-link:first-child { 12 | border-top-left-radius: 5px; 13 | border-bottom-left-radius: 5px; 14 | } 15 | .stcr-pagination-links .stcr-page-link:last-child { 16 | border-top-right-radius: 5px; 17 | border-bottom-right-radius: 5px; 18 | } -------------------------------------------------------------------------------- /src/includes/fonts/FontAwesome.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stcr/subscribe-to-comments-reloaded/0c1e269712d6cfd4fa938a29149eabc184ea9ae3/src/includes/fonts/FontAwesome.otf -------------------------------------------------------------------------------- /src/includes/fonts/fontawesome-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stcr/subscribe-to-comments-reloaded/0c1e269712d6cfd4fa938a29149eabc184ea9ae3/src/includes/fonts/fontawesome-webfont.eot -------------------------------------------------------------------------------- /src/includes/fonts/fontawesome-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stcr/subscribe-to-comments-reloaded/0c1e269712d6cfd4fa938a29149eabc184ea9ae3/src/includes/fonts/fontawesome-webfont.ttf -------------------------------------------------------------------------------- /src/includes/fonts/fontawesome-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stcr/subscribe-to-comments-reloaded/0c1e269712d6cfd4fa938a29149eabc184ea9ae3/src/includes/fonts/fontawesome-webfont.woff -------------------------------------------------------------------------------- /src/includes/fonts/fontawesome-webfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stcr/subscribe-to-comments-reloaded/0c1e269712d6cfd4fa938a29149eabc184ea9ae3/src/includes/fonts/fontawesome-webfont.woff2 -------------------------------------------------------------------------------- /src/includes/js/admin/management_page.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by reedyseth on 4/2/18. 3 | */ 4 | ( function($){ 5 | $(document).ready(function(){ 6 | 7 | var option_manager_page = $("input[name='options[manager_page]']" ); 8 | var missing_fields = []; 9 | 10 | // management_page_form 11 | $('form.management_page_form').submit(function(event){ 12 | if( option_manager_page.val() === "" ) 13 | { 14 | var field = "options[manager_page]"; 15 | 16 | if( ! checkArrayKey( missing_fields, field ) ) 17 | { 18 | missing_fields.push( // TODO: Only push if the array does not contain the key already. 19 | { 20 | message: "", 21 | field: field 22 | } ); 23 | } 24 | } 25 | 26 | var missing_fields_size = missing_fields.length; 27 | 28 | if( missing_fields_size > 0 ) 29 | { 30 | 31 | for( var i = 0; i < missing_fields_size; i++ ) 32 | { 33 | var field_obj = missing_fields[i]; 34 | // TODO: Implement the correct text messages with internationalization 35 | // $("form#add_new_subscription .validate-error-text-" + field_obj.field).text(field_obj.message).show(); 36 | $("form.management_page_form input[name='"+ field_obj.field +"']").addClass("validate-error-field"); 37 | $('html, body').animate({scrollTop:0}, 'slow'); 38 | 39 | missing_fields = []; // clean house 40 | return false; 41 | } 42 | 43 | } 44 | }); 45 | 46 | 47 | function checkArrayKey( arrayObj, keyToCheck ) 48 | { 49 | var size = arrayObj.length; 50 | 51 | for(var i = 0; i < size; i++) 52 | { 53 | if( arrayObj[i].field == keyToCheck ) 54 | { 55 | return true; 56 | } 57 | } 58 | return false; 59 | } 60 | }); 61 | } )( jQuery ); -------------------------------------------------------------------------------- /src/includes/js/admin/stcr_system.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Handles system page JavaScript 3 | */ 4 | 5 | jQuery(document).ready(function(){ 6 | 7 | jQuery('.download_report').on( 'click', function(e) { 8 | e.preventDefault(); 9 | jQuery('form[name="stcr_sysinfo_form"]').submit(); 10 | }); 11 | 12 | }); -------------------------------------------------------------------------------- /src/includes/js/admin/subs_management.js: -------------------------------------------------------------------------------- 1 | ( function($){ 2 | $(document).ready(function(){ 3 | 4 | var emailRegex = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; 5 | var oldsre_input = $("form#mass_update_address_form input[name='oldsre']"); 6 | var sre_input = $("form#mass_update_address_form input[name='sre']"); 7 | 8 | 9 | oldsre_input.focus(function(){ 10 | if (oldsre_input.val() == "") 11 | { 12 | oldsre_input.val(""); 13 | } 14 | oldsre_input.css("color","#000"); 15 | }); 16 | 17 | oldsre_input.blur(function(){ 18 | if (oldsre_input.val() == "") 19 | { 20 | oldsre_input.val(""); 21 | oldsre_input.css("color","#ccc"); 22 | } 23 | }); 24 | 25 | sre_input.focus(function(){ 26 | if (sre_input.val() == "") 27 | { 28 | sre_input.val(""); 29 | } 30 | sre_input.css("color","#000"); 31 | }); 32 | 33 | sre_input.blur(function(){ 34 | if (sre_input.val() == "") 35 | { 36 | sre_input.val(""); 37 | sre_input.css("color","#ccc"); 38 | } 39 | }); 40 | 41 | $("form#mass_update_address_form").submit(function(){ 42 | var old_email = $.trim( $("form#mass_update_address_form input[name='oldsre']").val() ); 43 | var email = $.trim( $("form#mass_update_address_form input[name='sre']").val() ); 44 | var missing_fields = []; 45 | 46 | if( old_email == "" || old_email == "") 47 | { 48 | missing_fields.push( 49 | { 50 | message: "", 51 | field: "oldsre" 52 | } ); 53 | } 54 | else if( ! emailRegex.test(old_email) ) // check valid email 55 | { 56 | missing_fields.push( 57 | { 58 | message: "", 59 | field: "oldsre" 60 | } ); 61 | } 62 | 63 | var missing_fields_size = missing_fields.length; 64 | 65 | if( missing_fields_size > 0 ) 66 | { 67 | 68 | for( var i = 0; i < missing_fields_size; i++ ) 69 | { 70 | var field_obj = missing_fields[i]; 71 | $("form#mass_update_address_form .validate-error-text-" + field_obj.field).text(field_obj.message).show(); 72 | $("form#mass_update_address_form input[name='"+ field_obj.field +"']").addClass("validate-error-field"); 73 | } 74 | 75 | return false; 76 | } 77 | else 78 | { 79 | var answer = confirm('Please remember: this operation cannot be undone. Are you sure you want to proceed?'); 80 | // var answer = confirm(''); 81 | if( ! answer ) 82 | { 83 | return false; 84 | } 85 | } 86 | 87 | 88 | }); 89 | // Add New Subscription 90 | var stcr_post_id_input = $("form#add_new_subscription input[name='srp']"); 91 | var sre_input = $("form#add_new_subscription textarea[name='sre']"); 92 | 93 | stcr_post_id_input.blur(function(){ 94 | if( $.isNumeric(stcr_post_id_input.val() ) ) // check numeric value 95 | { 96 | $(this).removeClass("validate-error-field"); 97 | $("form#add_new_subscription .validate-error-text-srp").hide(); 98 | } 99 | }); 100 | 101 | sre_input.blur(function(){ 102 | var sre_input_array = sre_input.val().replaceAll( ' ', '' ); 103 | sre_input_array = sre_input_array.split( ',' ); 104 | $.each( sre_input_array, function( index, value ) { 105 | if( emailRegex.test( value ) ) // check email value 106 | { 107 | $(sre_input).removeClass("validate-error-field"); 108 | $("form#add_new_subscription .validate-error-text-sre").hide(); 109 | } 110 | } ); 111 | }); 112 | 113 | $("form#add_new_subscription").submit(function(){ 114 | var post_id = $.trim(stcr_post_id_input.val()); 115 | var email = $.trim(sre_input.val()); 116 | var missing_fields = []; 117 | 118 | if( post_id == "") 119 | { 120 | missing_fields.push( 121 | { 122 | message: "", 123 | field: "srp" 124 | } ); 125 | } 126 | else if( ! $.isNumeric(post_id) ) // check numeric value 127 | { 128 | missing_fields.push( 129 | { 130 | message: "", 131 | field: "srp" 132 | } ); 133 | } 134 | 135 | if( email == "") 136 | { 137 | missing_fields.push( 138 | { 139 | message: "", 140 | field: "sre" 141 | } ); 142 | } 143 | else { 144 | var email_submit = email.replaceAll( ' ', '' ); 145 | email_submit = email_submit.split( ',' ); 146 | $.each( email_submit, function( index, value ) { 147 | if( ! emailRegex.test(value) ) // check valid email 148 | { 149 | missing_fields.push( 150 | { 151 | message: "", 152 | field: "sre" 153 | } ); 154 | } 155 | } ); 156 | 157 | } 158 | 159 | var missing_fields_size = missing_fields.length; 160 | 161 | if( missing_fields_size > 0 ) 162 | { 163 | 164 | for( var i = 0; i < missing_fields_size; i++ ) 165 | { 166 | var field_obj = missing_fields[i]; 167 | $("form#add_new_subscription .validate-error-text-" + field_obj.field).text(field_obj.message).show(); 168 | $("form#add_new_subscription input[name='"+ field_obj.field +"']").addClass("validate-error-field"); 169 | } 170 | 171 | return false; 172 | } 173 | }); 174 | 175 | var search_input = $("form#search_subscriptions_form input[name='srv']"); 176 | 177 | $("form#search_subscriptions_form").submit(function(){ 178 | var search_value = $.trim(search_input.val()); 179 | 180 | if( search_value == "") 181 | { 182 | search_input.val(""); 183 | search_input.addClass("validate-error-field"); 184 | 185 | return false; 186 | } 187 | }); 188 | 189 | search_input.focus(function(){ 190 | if( search_input.val() == "" ) 191 | { 192 | search_input.val(""); 193 | } 194 | }); 195 | 196 | search_input.blur(function(){ 197 | if( $.trim(search_input.val() ) != "" ) 198 | { 199 | $(this).removeClass("validate-error-field"); 200 | } 201 | }); 202 | }); 203 | 204 | // More info action 205 | $('div.more-info').on("click", function( event ) { 206 | event.preventDefault(); 207 | var info_panel = $( this ).data( "infopanel" ); 208 | info_panel = "." + info_panel; 209 | 210 | $( ".postbox-mass").css("overflow","hidden"); 211 | 212 | if( $( info_panel ).hasClass( "hidden") ) 213 | { 214 | $( info_panel ).slideDown( "fast" ); 215 | $( info_panel).removeClass( "hidden" ); 216 | } 217 | else 218 | { 219 | $( info_panel ).slideUp( "fast" ); 220 | $( info_panel).addClass( "hidden" ); 221 | } 222 | }); 223 | 224 | var subscribers_table = $("table.subscribers-table"); 225 | var lang_text_direction = stcr_i18n.langTextDirection; 226 | var dataTablesDOM = '<"float-left"f><"float-right"l>t'; 227 | 228 | // Check the text direction and set the correct DataTables dir. 229 | if ( lang_text_direction === "rtl" ) 230 | { 231 | dataTablesDOM = '<"float-right"f><"float-left"l>t<"float-right"i><"float-left"p>'; 232 | } 233 | 234 | var subscribers_table_dt = subscribers_table.DataTable( { 235 | columns: [ { sortable: false }, null, null, null, null], 236 | dom: dataTablesDOM, 237 | responsive: { 238 | details: true, 239 | type: 'column' 240 | }, 241 | columnDefs: [ 242 | { responsivePriority: 1, targets: 0 }, 243 | { responsivePriority: 2, targets: 3 }, 244 | { responsivePriority: 3, targets: 4 } 245 | ], 246 | language: stcr_i18n 247 | }); 248 | 249 | subscribers_table.removeClass("stcr-hidden"); 250 | $(".subs-spinner").hide(); 251 | // card-body 252 | var massUpdateSubsCollapse = $('.mass-update-subs .fa-caret-down'), 253 | massUpdateSubsCollapseState = true, 254 | addNewSubsCollapse = $('.add-new-subs .fa-caret-down'), 255 | addNewSubsCollapseState = true; 256 | 257 | $('.mass-update-subs h6').on('click', function () { 258 | 259 | if ( massUpdateSubsCollapseState ) 260 | { 261 | $(this).parent().find(".card-text").removeClass("stcr-hidden").addClass("original-card-padding"); 262 | 263 | massUpdateSubsCollapse.removeClass("fa-caret-down").addClass("fa-caret-up"); 264 | massUpdateSubsCollapseState = false; 265 | } 266 | else if ( ! massUpdateSubsCollapseState) 267 | { 268 | $(this).parent().find(".card-text").addClass("stcr-hidden").removeClass("original-card-padding"); 269 | 270 | massUpdateSubsCollapse.removeClass("fa-caret-up").addClass("fa-caret-down"); 271 | massUpdateSubsCollapseState = true; 272 | } 273 | }); 274 | 275 | $('.add-new-subs h6').on('click', function () { 276 | 277 | if ( addNewSubsCollapseState ) 278 | { 279 | $(this).parent().find(".card-text").removeClass("stcr-hidden").addClass("original-card-padding"); 280 | 281 | addNewSubsCollapse.removeClass("fa-caret-down").addClass("fa-caret-up"); 282 | addNewSubsCollapseState = false; 283 | } 284 | else if ( ! addNewSubsCollapseState) 285 | { 286 | $(this).parent().find(".card-text").addClass("stcr-hidden").removeClass("original-card-padding"); 287 | 288 | addNewSubsCollapse.removeClass("fa-caret-up").addClass("fa-caret-down"); 289 | addNewSubsCollapseState = true; 290 | } 291 | }); 292 | // Handle the checkbox selection 293 | subscribers_table.find("thead tr th").on("click","#stcr_select_all",function () { 294 | 295 | var table_rows = subscribers_table_dt.rows({ 'search': 'applied' }).nodes(); 296 | $('input[type="checkbox"]', table_rows).prop('checked', this.checked); 297 | 298 | }); 299 | 300 | 301 | } )( jQuery ); 302 | -------------------------------------------------------------------------------- /src/includes/js/admin/subs_options.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by reedyseth on 4/2/18. 3 | */ 4 | ( function($){ 5 | $(document).ready(function(){ 6 | $('.helpDescription').webuiPopover({ 7 | style: 'helpDescriptionContent', 8 | dismissible: true, 9 | type: 'html' 10 | }); 11 | 12 | }); 13 | } )( jQuery ); -------------------------------------------------------------------------------- /src/includes/js/stcr-admin.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Script to handle all the Admin actions. 3 | */ 4 | ( function($){ 5 | $(document).ready(function() { 6 | /** 7 | * Handle the notification dismiss action 8 | * @author reedyseth 9 | * @since 25-August-2015 10 | */ 11 | $('.stcr-dismiss-notice').on('click','a.dismiss', function() { 12 | var spinner = $( '' ); 13 | var nonce = $(this).parent().parent().data('nonce'); 14 | nonce = nonce.split('|'); 15 | var data = { 16 | action: nonce[1], 17 | security: nonce[0] 18 | }; 19 | _this = $( this ).parent().parent(); 20 | // Make the Ajax request. 21 | $.ajax({ 22 | type: "post", 23 | url: ajaxurl, 24 | data: data, 25 | beforeSend: function() { 26 | _this.find(".stcr-loading-animation").removeClass("stcr-loading-information").show(); 27 | }, 28 | success: function ( response ){ 29 | if ( response.success === true ) { 30 | _this.slideUp( 'fast' ); 31 | } 32 | //console.debug('Notice dismissed, server response >> ' + response ); 33 | }, 34 | error: function( error ) { 35 | //console.debug( error ); 36 | }, 37 | complete: function() { 38 | _this.find(".stcr-loading-animation").hide(); 39 | } 40 | }); //close jQuery.ajax 41 | }); 42 | 43 | /** 44 | * Control the execution of the options restore process. 45 | * @author reedyseth 46 | * @since 08-February-2018 47 | */ 48 | $('input.reset_all_options').on("click", function ( event ) { 49 | var confirmation = confirm("If you proceed this action cannot be undone, all settings will be wipe out"); 50 | 51 | return confirmation; 52 | }); 53 | }); 54 | } )( jQuery ); 55 | -------------------------------------------------------------------------------- /src/includes/js/stcr-plugin.js: -------------------------------------------------------------------------------- 1 | // 2 | // ( function($){ 3 | // /** 4 | // * Scripts to handle the plugin behavior. 5 | // * 6 | // * @since 22-Sep-2015 7 | // * @author reedyseth 8 | // */ 9 | // $(document).ready(function($){ 10 | // /** 11 | // * Move the Subscription box above the submit button 12 | // * @since 23-Sept-2015 13 | // * @author reedyseth 14 | // */ 15 | // var submit_button = $(':input[type="submit"]'); 16 | // var stcr_form = $('div.stcr-form'); 17 | // var stcr_form_html = stcr_form.html(); 18 | // 19 | // 20 | // stcr_form.prevUntil('form').each(function() { 21 | // var $this = $(this); // Cache this. 22 | // if($this.find(':input[type="submit"]').length) 23 | // { 24 | // stcr_form.remove(), $this.before(stcr_form); 25 | // $('div.stcr-form').removeClass( 'stcr-hidden' ); 26 | // return false; // Break the each() loop. 27 | // } 28 | // }); 29 | // }); 30 | // } )( jQuery ); 31 | 32 | 33 | -------------------------------------------------------------------------------- /src/includes/js/stcr-tinyMCE.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Initialize all the tinyMCE code. 3 | * @since 03-Aug-2015 4 | * @author reedyseth 5 | * @description Disabled to use the WordPress one. 6 | */ 7 | jQuery(document).ready(function() { 8 | // tinymce.init({ 9 | // selector: "textarea.rte", 10 | // plugins: [ 11 | // "link hr anchor code" 12 | // ] 13 | // }); 14 | }); 15 | -------------------------------------------------------------------------------- /src/includes/sass/_buttons.scss: -------------------------------------------------------------------------------- 1 | /* ---------------------------------------------------------- 2 | Styles use on form styles. Helpful to customize Bootstrap Buttons behavior. 3 | @author Israel Barragan (Reedyseth) 4 | @since 01-Apr-2018 5 | ---------------------------------------------------------- */ 6 | .btn { 7 | white-space: nowrap; 8 | } 9 | 10 | .btn-primary { 11 | color: #fff !important; 12 | background-color: #0085ba !important; 13 | border-color: #80bbd2 !important; 14 | } 15 | 16 | .btn-primary:hover { 17 | color: #fff !important; 18 | background-color: #4299b9 !important; 19 | border-color: #5495ad !important; 20 | } 21 | 22 | .btn-third { 23 | color: #444 !important; 24 | background-color: #ffc63c !important; 25 | border-color: #dcb456 !important; 26 | } 27 | 28 | .btn-third:hover { 29 | color: #444 !important; 30 | background-color: #fdd575 !important; 31 | border-color: #dcb456 !important; 32 | } 33 | 34 | .btn-download { 35 | color: #445435; 36 | background-color: #7bd774 !important; 37 | border-color: #28a745 !important; 38 | } 39 | 40 | 41 | .btn-download:hover { 42 | color: #445435; 43 | background-color: #78c771 !important; 44 | border-color: #28a745 !important; 45 | } 46 | -------------------------------------------------------------------------------- /src/includes/sass/_cards.scss: -------------------------------------------------------------------------------- 1 | /* ---------------------------------------------------------- 2 | Styles use on Cards styles. Helpful to customize Bootstrap Cards behavior. 3 | @author Israel Barragan (Reedyseth) 4 | @since 01-Apr-2018 5 | ---------------------------------------------------------- */ 6 | .card { 7 | padding: 0 !important; 8 | border-bottom: 0; 9 | } 10 | 11 | .card-subscribers { 12 | -webkit-box-shadow: 0 0 6px 0 #9E9E9E; 13 | box-shadow: 0 0 6px 0 #9E9E9E; 14 | } 15 | 16 | .card-header{ 17 | background-color: #008ec2 !important; 18 | color: #ffffff; 19 | } 20 | 21 | .card-font-size { 22 | font-size: 0.85em; 23 | } 24 | 25 | .original-card-padding { 26 | padding: 1.25rem !important; 27 | } 28 | 29 | .card-no-max-width { 30 | max-width: 100% !important; 31 | } 32 | -------------------------------------------------------------------------------- /src/includes/sass/_forms.scss: -------------------------------------------------------------------------------- 1 | /* ---------------------------------------------------------- 2 | Styles use on form styles. Helpful to customize Bootstrap behavior. 3 | @author Israel Barragan (Reedyseth) 4 | @since 01-Apr-2018 5 | ---------------------------------------------------------- */ 6 | .form-controls-font { 7 | font-size: 1em !important; 8 | 9 | } 10 | 11 | .col-form-label { 12 | font-size: 0.95rem !important; 13 | font-weight: 600 !important; 14 | } 15 | 16 | .subscribers-mass-actions 17 | { 18 | margin-top: 20px; 19 | font-size: 0.9rem; 20 | } 21 | 22 | .subscribers-mass-actions select, 23 | .subscribers-mass-actions button, 24 | .subscribers-mass-actions input 25 | { 26 | font-size: 0.9rem !important; 27 | } 28 | 29 | .mass-update-subs { 30 | /*height: 100%;*/ 31 | margin-top: 0 !important; 32 | } 33 | 34 | .mass-update-select-status { 35 | width: 70% !important; 36 | display: inline !important; 37 | } 38 | 39 | .new-sub-select-status { 40 | width: 76% !important; 41 | display: inline !important; 42 | } 43 | 44 | .form-control { 45 | height: auto !important; 46 | } 47 | 48 | .form-control-select { 49 | width: 42% !important; 50 | display: inline !important; 51 | font-size: 0.9rem !important; 52 | } 53 | 54 | .form-control-input-3 { 55 | width: 30% !important; 56 | display: inline !important; 57 | font-size: 0.9rem !important; 58 | } 59 | 60 | .form-control-input-4 { 61 | width: 40% !important; 62 | display: inline !important; 63 | font-size: 0.9rem !important; 64 | } 65 | 66 | .form-control-input-5 { 67 | width: 50% !important; 68 | display: inline !important; 69 | font-size: 0.9rem !important; 70 | } 71 | 72 | .form-control-input-6 { 73 | width: 60% !important; 74 | display: inline !important; 75 | font-size: 0.9rem !important; 76 | } 77 | 78 | .form-control-input-7 { 79 | width: 70% !important; 80 | display: inline !important; 81 | font-size: 0.9rem !important; 82 | } 83 | 84 | .form-control-input-8 { 85 | width: 80% !important; 86 | display: inline !important; 87 | font-size: 0.9rem !important; 88 | } 89 | 90 | .form-control-input-9 { 91 | width: 90% !important; 92 | display: inline !important; 93 | font-size: 0.9rem !important; 94 | } 95 | 96 | .add-new-subs { 97 | /*height: 100%;*/ 98 | margin-top: 0 !important; 99 | } 100 | 101 | .mass-update-subs h6, 102 | .add-new-subs h6 { 103 | cursor: pointer; 104 | } 105 | 106 | .subscribe-form-button { 107 | font-size: 0.8rem !important; 108 | } 109 | 110 | // https://php.quicoto.com/toggle-switches-using-input-radio-and-css3/ 111 | .switch { 112 | position: relative; 113 | display: inline-flex; 114 | margin-top: 7px; 115 | height: 26px; 116 | width: 120px; 117 | background: rgba(45, 43, 42, 0.1); 118 | border-radius: 3px; 119 | -webkit-box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.13), 0 1px rgba(255, 255, 255, 0.1); 120 | box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.13), 0 1px rgba(255, 255, 255, 0.1); 121 | } 122 | 123 | .switch-label { 124 | position: relative; 125 | z-index: 2; 126 | float: left; 127 | width: 58px; 128 | line-height: 26px; 129 | font-size: 11px; 130 | color: rgba(148, 148, 148, 1); 131 | text-align: center; 132 | text-shadow: 0 1px 1px rgba(0, 0, 0, 0.45); 133 | cursor: pointer; 134 | } 135 | 136 | .switch-label:active { 137 | font-weight: bold; 138 | } 139 | 140 | .switch-label-off { 141 | padding-left: 2px; 142 | } 143 | 144 | .switch-label-on { 145 | padding-right: 2px; 146 | } 147 | 148 | .switch-input { 149 | display: none !important; 150 | } 151 | 152 | .switch-input:checked + .switch-label { 153 | font-weight: bold; 154 | color: rgba(0, 0, 0, 0.65); 155 | text-shadow: 0 1px rgba(255, 255, 255, 0.25); 156 | -webkit-transition: 0.15s ease-out; 157 | -moz-transition: 0.15s ease-out; 158 | -o-transition: 0.15s ease-out; 159 | transition: 0.15s ease-out; 160 | } 161 | 162 | $switch-initial-bg: #46d443; 163 | $switch-final-bg: #9dd993; 164 | $switch-initial-bg-dis: #82928f; 165 | $switch-final-bg-dis: #f3e4f6; 166 | 167 | .switch-input:checked + .switch-label-on ~ .switch-selection{ 168 | /* Note: left: 50% doesn't transition in WebKit */ 169 | left: 60px; 170 | background-image: -webkit-linear-gradient(top, $switch-final-bg-dis, $switch-initial-bg-dis); 171 | background-image: -moz-linear-gradient(top, $switch-final-bg-dis, $switch-initial-bg-dis); 172 | background-image: -o-linear-gradient(top, $switch-final-bg-dis, $switch-initial-bg-dis); 173 | background-image: linear-gradient(to bottom, $switch-final-bg-dis, $switch-initial-bg-dis); 174 | } 175 | 176 | .switch-selection { 177 | display: block; 178 | position: absolute; 179 | z-index: 1; 180 | top: 2px; 181 | left: 2px; 182 | width: 58px; 183 | height: 22px; 184 | background: #65bd63; 185 | border-radius: 3px; 186 | background-image: -webkit-linear-gradient(top, $switch-final-bg, $switch-initial-bg); 187 | background-image: -moz-linear-gradient(top, $switch-final-bg, $switch-initial-bg); 188 | background-image: -o-linear-gradient(top, $switch-final-bg, $switch-initial-bg); 189 | background-image: linear-gradient(to bottom, $switch-final-bg, $switch-initial-bg); 190 | -webkit-box-shadow: inset 0 1px rgba(255, 255, 255, 0.5), 0 0 2px rgba(0, 0, 0, 0.2); 191 | box-shadow: inset 0 1px rgba(255, 255, 255, 0.5), 0 0 2px rgba(0, 0, 0, 0.2); 192 | -webkit-transition: left 0.15s ease-out; 193 | -moz-transition: left 0.15s ease-out; 194 | -o-transition: left 0.15s ease-out; 195 | transition: left 0.15s ease-out; 196 | } 197 | 198 | .switch-blue .switch-selection { 199 | background: #3aa2d0; 200 | background-image: -webkit-linear-gradient(top, #4fc9ee, #3aa2d0); 201 | background-image: -moz-linear-gradient(top, #4fc9ee, #3aa2d0); 202 | background-image: -o-linear-gradient(top, #4fc9ee, #3aa2d0); 203 | background-image: linear-gradient(to bottom, #4fc9ee, #3aa2d0); 204 | } 205 | 206 | .switch-yellow .switch-selection { 207 | background: #c4bb61; 208 | background-image: -webkit-linear-gradient(top, #e0dd94, #c4bb61); 209 | background-image: -moz-linear-gradient(top, #e0dd94, #c4bb61); 210 | background-image: -o-linear-gradient(top, #e0dd94, #c4bb61); 211 | background-image: linear-gradient(to bottom, #e0dd94, #c4bb61); 212 | } 213 | 214 | .helpDescription { 215 | margin-left: 10px; 216 | display: inline-flex; 217 | color: #008ec2; 218 | font-size: 0.9rem; 219 | cursor: pointer; 220 | } 221 | 222 | .webui-popover-helpDescriptionContent { 223 | font-size: 0.85rem; 224 | } 225 | 226 | 227 | .arrow { 228 | left: -8px !important; 229 | } 230 | 231 | .arrow:after{ 232 | left: 4px !important; 233 | top: 0px !important; 234 | width: 17px !important; 235 | height: 2px !important; 236 | } 237 | //.popover .arrow { 238 | // position: absolute; 239 | // display: block; 240 | // width: 1rem !important; 241 | // height: .5rem !important; 242 | // margin: 0 .3rem !important; 243 | //} 244 | 245 | select.form-control:not([size]):not([multiple]) { 246 | height: calc(2.25rem + 2px) !important; 247 | } 248 | 249 | .input-group-sm > .input-group-append > select.btn:not([size]):not([multiple]), .input-group-sm > .input-group-append > select.input-group-text:not([size]):not([multiple]), .input-group-sm > .input-group-prepend > select.btn:not([size]):not([multiple]), .input-group-sm > .input-group-prepend > select.input-group-text:not([size]):not([multiple]), .input-group-sm > select.form-control:not([size]):not([multiple]), select.form-control-sm:not([size]):not([multiple]) { 250 | height: calc(1.8125rem + 2px) !important; 251 | } 252 | -------------------------------------------------------------------------------- /src/includes/sass/_init.scss: -------------------------------------------------------------------------------- 1 | .h1, .h2, .h3, .h4, .h5, .h6, h1, h2, h3, h4, h5, h6 { 2 | color: inherit; 3 | } 4 | -------------------------------------------------------------------------------- /src/includes/sass/_interactions.scss: -------------------------------------------------------------------------------- 1 | /* ---------------------------------------------------------- 2 | Styles use on the interaction with the user. 3 | @author Israel Barragan (Reedyseth) 4 | @since 01-Apr-2018 5 | ---------------------------------------------------------- */ 6 | 7 | .stcr-loading-animation { 8 | display: none; 9 | } 10 | 11 | .dismiss { 12 | background: #00a0d2; 13 | border-color: #0073aa; 14 | -webkit-box-shadow: inset 0 1px 0 rgba(120,200,230,.5),0 1px 0 rgba(0,0,0,.15); 15 | box-shadow: inset 0 1px 0 rgba(120,200,230,.5),0 1px 0 rgba(0,0,0,.15); 16 | color: #fff; 17 | text-decoration: none; 18 | display: inline-block; 19 | text-decoration: none; 20 | font-size: 13px; 21 | line-height: 26px; 22 | height: 28px; 23 | margin: 0 0 0 10px; 24 | padding: 0 10px 1px; 25 | cursor: pointer; 26 | border-width: 1px; 27 | border-style: solid; 28 | -webkit-appearance: none; 29 | -webkit-border-radius: 3px; 30 | border-radius: 3px; 31 | white-space: nowrap; 32 | -webkit-box-sizing: border-box; 33 | -moz-box-sizing: border-box; 34 | box-sizing: border-box; 35 | } 36 | 37 | .dismiss:hover { 38 | background: #0091cd; 39 | border-color: #0073aa; 40 | -webkit-box-shadow: inset 0 1px 0 rgba(120,200,230,.6); 41 | box-shadow: inset 0 1px 0 rgba(120,200,230,.6); 42 | color: #fff; 43 | } 44 | 45 | .info-panel { 46 | background-color: #BBBBBB; 47 | padding: 8px; 48 | font-style: italic; 49 | } 50 | 51 | .more-info 52 | { 53 | color: #008ec2; 54 | cursor: pointer; 55 | width: 10%; 56 | font-size: 1.4rem; 57 | } 58 | 59 | .stcr-dismiss-notice { 60 | 61 | p { 62 | font-size: 0.8rem !important; 63 | } 64 | 65 | h2 { 66 | font-size: 1rem !important; 67 | } 68 | } 69 | 70 | li { 71 | margin-bottom: 0; 72 | } 73 | 74 | .navbar-expand-lg .navbar-nav .dropdown-menu { 75 | top: 30px; 76 | font-size: 0.9rem; 77 | } -------------------------------------------------------------------------------- /src/includes/sass/_spinners.scss: -------------------------------------------------------------------------------- 1 | /* ---------------------------------------------------------- 2 | Styles use on loading events. 3 | @author Israel Barragan (Reedyseth) 4 | @since 01-Apr-2018 5 | ---------------------------------------------------------- */ 6 | .fa-spinner, .fa-play-circle { 7 | color: #ffc53a; 8 | -webkit-animation-name: spin; 9 | -webkit-animation-duration: 900ms; 10 | -webkit-animation-iteration-count: infinite; 11 | -webkit-animation-timing-function: cubic-bezier(0.4, 0.62, 0.93, 0.98); 12 | -moz-animation-name: spin; 13 | -moz-animation-duration: 900ms; 14 | -moz-animation-iteration-count: infinite; 15 | -moz-animation-timing-function: cubic-bezier(0.4, 0.62, 0.93, 0.98); 16 | -ms-animation-name: spin; 17 | -ms-animation-duration: 900ms; 18 | -ms-animation-iteration-count: infinite; 19 | -ms-animation-timing-function: cubic-bezier(0.4, 0.62, 0.93, 0.98); 20 | 21 | animation-name: spin; 22 | animation-duration: 900ms; 23 | animation-iteration-count: infinite; 24 | animation-timing-function: cubic-bezier(0.4, 0.62, 0.93, 0.98); 25 | } 26 | @-ms-keyframes spin { 27 | from { -ms-transform: rotate(0deg); } 28 | to { -ms-transform: rotate(360deg); } 29 | } 30 | @-moz-keyframes spin { 31 | from { -moz-transform: rotate(0deg); } 32 | to { -moz-transform: rotate(360deg); } 33 | } 34 | @-webkit-keyframes spin { 35 | from { -webkit-transform: rotate(0deg); } 36 | to { -webkit-transform: rotate(360deg); } 37 | } 38 | @keyframes spin { 39 | from { 40 | transform:rotate(0deg); 41 | } 42 | to { 43 | transform:rotate(360deg); 44 | } 45 | } -------------------------------------------------------------------------------- /src/includes/sass/_tables.scss: -------------------------------------------------------------------------------- 1 | /* ---------------------------------------------------------- 2 | Styles use on Table styles. Helpful to customize Bootstrap Tables behavior. 3 | @author Israel Barragan (Reedyseth) 4 | @since 01-Apr-2018 5 | ---------------------------------------------------------- */ 6 | .table { 7 | color: #464646 !important; 8 | } 9 | 10 | table.subscribers-table { 11 | width: 100% !important; 12 | } 13 | 14 | table.subscribers-table thead{ 15 | background-color: #b3e0f1; 16 | } 17 | 18 | table.subscribers-table thead th{ 19 | line-height: normal; 20 | vertical-align: middle; 21 | padding: 0.55rem; 22 | } 23 | 24 | table.subscribers-table thead th:first-child { 25 | width: 15%; 26 | text-align: center; 27 | } 28 | 29 | table.subscribers-table tbody tr td:first-child { 30 | text-align: center; 31 | } 32 | 33 | table.subscribers-table thead th i{ 34 | margin-right: 5px; 35 | font-size: 1.0rem; 36 | } 37 | table.subscribers-table thead th span{ 38 | vertical-align: text-bottom; 39 | font-size: 0.9rem; 40 | text-transform: uppercase; 41 | } 42 | 43 | @media screen and ( max-width: 651px ) { 44 | table.dataTable.dtr-inline.collapsed>tbody>tr[role="row"]>td:first-child, 45 | table.dataTable.dtr-inline.collapsed>tbody>tr[role="row"]>th:first-child { 46 | padding-left: 40px !important; 47 | } 48 | } 49 | 50 | @media screen and ( max-width: 350px ) { 51 | table.dataTable.dtr-inline.collapsed>tbody>tr[role="row"]>td:first-child, 52 | table.dataTable.dtr-inline.collapsed>tbody>tr[role="row"]>th:first-child { 53 | padding-left: 57px !important; 54 | } 55 | } 56 | 57 | /* Override rules from DataTables causing styling issues.*/ 58 | .dataTables_wrapper .dataTables_paginate .paginate_button 59 | { 60 | padding: 0 !important; 61 | margin-left: 0 !important; 62 | border: none !important; 63 | border-radius: 0px !important; 64 | } 65 | 66 | .dataTables_wrapper .dataTables_paginate .paginate_button:hover, 67 | .dataTables_wrapper .dataTables_paginate .paginate_button:hover { 68 | background: none !important; 69 | -webkit-box-shadow: none !important; 70 | -moz-box-shadow: none !important; 71 | box-shadow: none !important; 72 | } 73 | 74 | .system-info-table a { 75 | color: #0073aa; 76 | } 77 | -------------------------------------------------------------------------------- /src/includes/sass/_utils.scss: -------------------------------------------------------------------------------- 1 | /* ---------------------------------------------------------- 2 | Common styles and utilities on pages. 3 | @author Israel Barragan (Reedyseth) 4 | @since 01-Apr-2018 5 | ---------------------------------------------------------- */ 6 | .validate-error-text 7 | { 8 | color: #f55252; 9 | font-weight:bold; 10 | } 11 | 12 | .validate-error-field { border: 1px solid #ff9595 !important; } 13 | 14 | .stcr-hidden { 15 | position: absolute !important; 16 | top: -9999px !important; 17 | left: -9999px !important; 18 | } 19 | 20 | .clearFix { 21 | clear: both; 22 | } 23 | 24 | .hidden { 25 | display: none; 26 | } 27 | 28 | .float-right { 29 | float: right; 30 | } 31 | 32 | .float-left { 33 | float: left; 34 | } 35 | 36 | .stcr-alert-box { 37 | font-size: .85em; 38 | } -------------------------------------------------------------------------------- /src/includes/sass/stcr-admin-style.scss: -------------------------------------------------------------------------------- 1 | /* 2 | Admin styles for StCR. 3 | 4 | @author reedyseth 5 | @since 21-Sep-2015 6 | */ 7 | 8 | @import 'init'; 9 | @import 'utils'; 10 | @import 'interactions'; 11 | @import 'forms'; 12 | @import 'cards'; 13 | @import 'tables'; 14 | @import 'buttons'; 15 | @import 'spinners'; 16 | 17 | -------------------------------------------------------------------------------- /src/includes/sass/stcr-style.scss: -------------------------------------------------------------------------------- 1 | .stcr-pagination-links { 2 | display: flex; 3 | flex-wrap: wrap; 4 | 5 | .stcr-page-link { 6 | display: block; 7 | padding: 5px 15px; 8 | margin-left: -1px; 9 | border: 1px solid #eaeaea; 10 | 11 | &:first-child { 12 | border-top-left-radius: 5px; 13 | border-bottom-left-radius: 5px; 14 | } 15 | 16 | &:last-child { 17 | border-top-right-radius: 5px; 18 | border-bottom-right-radius: 5px; 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/includes/webfonts/fa-brands-400.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stcr/subscribe-to-comments-reloaded/0c1e269712d6cfd4fa938a29149eabc184ea9ae3/src/includes/webfonts/fa-brands-400.eot -------------------------------------------------------------------------------- /src/includes/webfonts/fa-brands-400.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stcr/subscribe-to-comments-reloaded/0c1e269712d6cfd4fa938a29149eabc184ea9ae3/src/includes/webfonts/fa-brands-400.ttf -------------------------------------------------------------------------------- /src/includes/webfonts/fa-brands-400.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stcr/subscribe-to-comments-reloaded/0c1e269712d6cfd4fa938a29149eabc184ea9ae3/src/includes/webfonts/fa-brands-400.woff -------------------------------------------------------------------------------- /src/includes/webfonts/fa-brands-400.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stcr/subscribe-to-comments-reloaded/0c1e269712d6cfd4fa938a29149eabc184ea9ae3/src/includes/webfonts/fa-brands-400.woff2 -------------------------------------------------------------------------------- /src/includes/webfonts/fa-regular-400.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stcr/subscribe-to-comments-reloaded/0c1e269712d6cfd4fa938a29149eabc184ea9ae3/src/includes/webfonts/fa-regular-400.eot -------------------------------------------------------------------------------- /src/includes/webfonts/fa-regular-400.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stcr/subscribe-to-comments-reloaded/0c1e269712d6cfd4fa938a29149eabc184ea9ae3/src/includes/webfonts/fa-regular-400.ttf -------------------------------------------------------------------------------- /src/includes/webfonts/fa-regular-400.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stcr/subscribe-to-comments-reloaded/0c1e269712d6cfd4fa938a29149eabc184ea9ae3/src/includes/webfonts/fa-regular-400.woff -------------------------------------------------------------------------------- /src/includes/webfonts/fa-regular-400.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stcr/subscribe-to-comments-reloaded/0c1e269712d6cfd4fa938a29149eabc184ea9ae3/src/includes/webfonts/fa-regular-400.woff2 -------------------------------------------------------------------------------- /src/includes/webfonts/fa-solid-900.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stcr/subscribe-to-comments-reloaded/0c1e269712d6cfd4fa938a29149eabc184ea9ae3/src/includes/webfonts/fa-solid-900.eot -------------------------------------------------------------------------------- /src/includes/webfonts/fa-solid-900.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stcr/subscribe-to-comments-reloaded/0c1e269712d6cfd4fa938a29149eabc184ea9ae3/src/includes/webfonts/fa-solid-900.ttf -------------------------------------------------------------------------------- /src/includes/webfonts/fa-solid-900.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stcr/subscribe-to-comments-reloaded/0c1e269712d6cfd4fa938a29149eabc184ea9ae3/src/includes/webfonts/fa-solid-900.woff -------------------------------------------------------------------------------- /src/includes/webfonts/fa-solid-900.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stcr/subscribe-to-comments-reloaded/0c1e269712d6cfd4fa938a29149eabc184ea9ae3/src/includes/webfonts/fa-solid-900.woff2 -------------------------------------------------------------------------------- /src/langs/subscribe-to-comments-reloaded-ar.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stcr/subscribe-to-comments-reloaded/0c1e269712d6cfd4fa938a29149eabc184ea9ae3/src/langs/subscribe-to-comments-reloaded-ar.mo -------------------------------------------------------------------------------- /src/langs/subscribe-to-comments-reloaded-be_BY.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stcr/subscribe-to-comments-reloaded/0c1e269712d6cfd4fa938a29149eabc184ea9ae3/src/langs/subscribe-to-comments-reloaded-be_BY.mo -------------------------------------------------------------------------------- /src/langs/subscribe-to-comments-reloaded-cs_CZ.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stcr/subscribe-to-comments-reloaded/0c1e269712d6cfd4fa938a29149eabc184ea9ae3/src/langs/subscribe-to-comments-reloaded-cs_CZ.mo -------------------------------------------------------------------------------- /src/langs/subscribe-to-comments-reloaded-da_DK.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stcr/subscribe-to-comments-reloaded/0c1e269712d6cfd4fa938a29149eabc184ea9ae3/src/langs/subscribe-to-comments-reloaded-da_DK.mo -------------------------------------------------------------------------------- /src/langs/subscribe-to-comments-reloaded-es_ES.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stcr/subscribe-to-comments-reloaded/0c1e269712d6cfd4fa938a29149eabc184ea9ae3/src/langs/subscribe-to-comments-reloaded-es_ES.mo -------------------------------------------------------------------------------- /src/langs/subscribe-to-comments-reloaded-fa_IR.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stcr/subscribe-to-comments-reloaded/0c1e269712d6cfd4fa938a29149eabc184ea9ae3/src/langs/subscribe-to-comments-reloaded-fa_IR.mo -------------------------------------------------------------------------------- /src/langs/subscribe-to-comments-reloaded-fr_FR.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stcr/subscribe-to-comments-reloaded/0c1e269712d6cfd4fa938a29149eabc184ea9ae3/src/langs/subscribe-to-comments-reloaded-fr_FR.mo -------------------------------------------------------------------------------- /src/langs/subscribe-to-comments-reloaded-he_IL.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stcr/subscribe-to-comments-reloaded/0c1e269712d6cfd4fa938a29149eabc184ea9ae3/src/langs/subscribe-to-comments-reloaded-he_IL.mo -------------------------------------------------------------------------------- /src/langs/subscribe-to-comments-reloaded-hu_HU.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stcr/subscribe-to-comments-reloaded/0c1e269712d6cfd4fa938a29149eabc184ea9ae3/src/langs/subscribe-to-comments-reloaded-hu_HU.mo -------------------------------------------------------------------------------- /src/langs/subscribe-to-comments-reloaded-id_ID.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stcr/subscribe-to-comments-reloaded/0c1e269712d6cfd4fa938a29149eabc184ea9ae3/src/langs/subscribe-to-comments-reloaded-id_ID.mo -------------------------------------------------------------------------------- /src/langs/subscribe-to-comments-reloaded-it_IT.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stcr/subscribe-to-comments-reloaded/0c1e269712d6cfd4fa938a29149eabc184ea9ae3/src/langs/subscribe-to-comments-reloaded-it_IT.mo -------------------------------------------------------------------------------- /src/langs/subscribe-to-comments-reloaded-nb_NO.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stcr/subscribe-to-comments-reloaded/0c1e269712d6cfd4fa938a29149eabc184ea9ae3/src/langs/subscribe-to-comments-reloaded-nb_NO.mo -------------------------------------------------------------------------------- /src/langs/subscribe-to-comments-reloaded-nl_NL.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stcr/subscribe-to-comments-reloaded/0c1e269712d6cfd4fa938a29149eabc184ea9ae3/src/langs/subscribe-to-comments-reloaded-nl_NL.mo -------------------------------------------------------------------------------- /src/langs/subscribe-to-comments-reloaded-pl_PL.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stcr/subscribe-to-comments-reloaded/0c1e269712d6cfd4fa938a29149eabc184ea9ae3/src/langs/subscribe-to-comments-reloaded-pl_PL.mo -------------------------------------------------------------------------------- /src/langs/subscribe-to-comments-reloaded-pt_BR.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stcr/subscribe-to-comments-reloaded/0c1e269712d6cfd4fa938a29149eabc184ea9ae3/src/langs/subscribe-to-comments-reloaded-pt_BR.mo -------------------------------------------------------------------------------- /src/langs/subscribe-to-comments-reloaded-pt_PT.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stcr/subscribe-to-comments-reloaded/0c1e269712d6cfd4fa938a29149eabc184ea9ae3/src/langs/subscribe-to-comments-reloaded-pt_PT.mo -------------------------------------------------------------------------------- /src/langs/subscribe-to-comments-reloaded-sr_RS.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stcr/subscribe-to-comments-reloaded/0c1e269712d6cfd4fa938a29149eabc184ea9ae3/src/langs/subscribe-to-comments-reloaded-sr_RS.mo -------------------------------------------------------------------------------- /src/langs/subscribe-to-comments-reloaded-sv_SE.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stcr/subscribe-to-comments-reloaded/0c1e269712d6cfd4fa938a29149eabc184ea9ae3/src/langs/subscribe-to-comments-reloaded-sv_SE.mo -------------------------------------------------------------------------------- /src/langs/subscribe-to-comments-reloaded-tr_TR.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stcr/subscribe-to-comments-reloaded/0c1e269712d6cfd4fa938a29149eabc184ea9ae3/src/langs/subscribe-to-comments-reloaded-tr_TR.mo -------------------------------------------------------------------------------- /src/langs/subscribe-to-comments-reloaded-zh_CN.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stcr/subscribe-to-comments-reloaded/0c1e269712d6cfd4fa938a29149eabc184ea9ae3/src/langs/subscribe-to-comments-reloaded-zh_CN.mo -------------------------------------------------------------------------------- /src/options/index.php: -------------------------------------------------------------------------------- 1 | 11 | 12 | 23 | -------------------------------------------------------------------------------- /src/options/options_template.php: -------------------------------------------------------------------------------- 1 | 'yesno', 16 | 'safely_uninstall' => 'yesno', 17 | 'purge_days' => 'integer', 18 | 'date_format' => 'text', 19 | 'stcr_position' => 'yesno', 20 | 'enable_double_check' => 'yesno', 21 | 'notify_authors' => 'yesno', 22 | 'enable_html_emails' => 'yesno', 23 | 'process_trackbacks' => 'yesno', 24 | 'enable_admin_messages' => 'yesno', 25 | 'admin_subscribe' => 'yesno', 26 | 'admin_bcc' => 'yesno', 27 | 'enable_font_awesome' => 'yesno', 28 | 'delete_options_subscriptions' => 'yesno', 29 | 'only_for_logged_in' => 'yesno', 30 | 'use_cookies' => 'yesno', 31 | 'use_challenge_question' => 'yesno', 32 | 'challenge_question' => 'text', 33 | 'challenge_answer' => 'text', 34 | 'use_captcha' => 'yesno', 35 | 'captcha_site_key' => 'text', 36 | 'captcha_secret_key' => 'text', 37 | 'allow_subscribe_without_comment' => 'yesno', 38 | 'allow_request_management_link' => 'yesno', 39 | 'recaptcha_version' => 'select', 40 | 'blacklisted_emails' => 'textarea', 41 | 'post_type_supports' => 'multicheck', 42 | ); 43 | 44 | // Update options 45 | if ( isset( $_POST['options'] ) ) { 46 | 47 | if ( empty( $_POST['stcr_action_nonce'] ) ) { 48 | return; 49 | } 50 | 51 | if ( ! wp_verify_nonce( $_POST['stcr_action_nonce'], 'stcr_action_nonce' ) ) { 52 | return; 53 | } 54 | 55 | if ( ! current_user_can( 'manage_options' ) ) { 56 | return; 57 | } 58 | 59 | $faulty_fields = array(); 60 | $subscribe_options = wp_unslash( $_POST['options'] ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput 61 | $subscribe_options = array_map( 62 | array( 63 | 'stcr\stcr_utils', 64 | 'sanitize_options' 65 | ), 66 | $subscribe_options 67 | ); 68 | foreach ( $subscribe_options as $option => $value ) 69 | { 70 | if ( ! $wp_subscribe_reloaded->stcr->utils->stcr_update_menu_options( $option, $value, $options[$option] ) ) 71 | { 72 | array_push( $faulty_fields, $option ); 73 | } 74 | } 75 | 76 | // Display an alert in the admin interface if something went wrong 77 | echo '

'; 78 | if ( sizeof( $faulty_fields ) == 0 ) { 79 | esc_html_e( 'Your settings have been successfully updated.', 'subscribe-to-comments-reloaded' ); 80 | } else { 81 | esc_html_e( 'There was an error updating the options.', 'subscribe-to-comments-reloaded' ); 82 | // echo ' ' . substr( $faulty_fields, 0, - 2 ) . ''; 83 | } 84 | echo '

'; 85 | } 86 | wp_print_scripts( 'quicktags' ); 87 | 88 | ?> 89 |
90 |
91 |
92 |
93 |
94 | 95 | 96 | 97 |
98 |
99 | 102 |
103 |
104 | 105 | 106 | 107 |
108 |
109 | 110 |
111 |
112 |
113 |

114 | Thank you for using Subscribe to Comments Reloaded. You can Support the plugin by rating it 115 | Rate Subscribe to Comments Reloaded 116 |

117 |

118 | Having issues? Please create a ticket 119 |

120 |
121 |
122 |
123 | 124 |
125 |
126 | stcr->utils->register_script_to_wp( "stcr-subs-options", "subs_options.js", "includes/js/admin"); 130 | // Includes the Panel JS resource file as well as the JS text domain translations. 131 | //$wp_subscribe_reloaded->stcr->stcr_i18n->stcr_localize_script( "stcr-subs-options", "stcr_i18n", $wp_subscribe_reloaded->stcr->stcr_i18n->get_js_subs_translation() ); 132 | // Enqueue the JS File 133 | $wp_subscribe_reloaded->stcr->utils->enqueue_script_to_wp( "stcr-subs-options" ); 134 | 135 | ?> 136 | -------------------------------------------------------------------------------- /src/options/panel1-add-subscription.php: -------------------------------------------------------------------------------- 1 | 7 |
8 |

9 | 10 |
12 |
13 |

14 | ' . esc_html( get_the_title( intval( $_GET['srp'] ) ) ) . ' (' . intval( $_GET['srp'] ) . ')'; 17 | ?> 18 |

19 | 20 |

21 | 22 | 23 |

24 | 25 |

26 | 31 | ' /> 32 |

33 | 34 | ' /> 35 |
36 | 37 | 38 | 39 |
40 |
41 | -------------------------------------------------------------------------------- /src/options/panel1-business-logic.php: -------------------------------------------------------------------------------- 1 | stcr->utils->check_valid_email( $subscriber_email ); 37 | } 38 | 39 | $valid_post_id = $wp_subscribe_reloaded->stcr->utils->check_valid_number( $post_id ); 40 | 41 | if ( $stcr_post_email === false ) 42 | { 43 | $valid_email = false; 44 | break; 45 | } 46 | 47 | if ( $valid_post_id === false ) 48 | { 49 | break; 50 | } 51 | 52 | foreach ( $subscriber_post_email as $subscriber_email ) { 53 | $wp_subscribe_reloaded->stcr->add_subscription( $post_id, $subscriber_email, $status ); 54 | 55 | if ( strpos( $status, 'C' ) !== false ) { 56 | $wp_subscribe_reloaded->stcr->confirmation_email( $post_id, $subscriber_email ); 57 | } 58 | } 59 | 60 | echo '

' . esc_html__( 'Subscription added.', 'subscribe-to-comments-reloaded' ) . '

'; 61 | break; 62 | 63 | case 'edit': 64 | 65 | if ( empty( $_POST['stcr_edit_subscription_nonce'] ) ) { 66 | exit(); 67 | } 68 | 69 | if ( ! wp_verify_nonce( $_POST['stcr_edit_subscription_nonce'], 'stcr_edit_subscription_nonce' ) ) { 70 | exit(); 71 | } 72 | 73 | if ( ! current_user_can( 'manage_options' ) ) { 74 | exit(); 75 | } 76 | 77 | $stcr_post_email = $wp_subscribe_reloaded->stcr->utils->check_valid_email( $stcr_post_email ); 78 | $stcr_old_post_email = $wp_subscribe_reloaded->stcr->utils->check_valid_email( $stcr_old_post_email ); 79 | $valid_post_id = $wp_subscribe_reloaded->stcr->utils->check_valid_number( $post_id ); 80 | 81 | if ( $stcr_post_email === false || $stcr_old_post_email === false ) 82 | { 83 | $valid_email = false; 84 | break; 85 | } 86 | 87 | if ( $valid_post_id === false ) 88 | { 89 | break; 90 | } 91 | 92 | $old_email = $stcr_old_post_email; 93 | $new_email = $stcr_post_email; 94 | 95 | $wp_subscribe_reloaded->stcr->update_subscription_status( $post_id, $old_email, $status ); 96 | $wp_subscribe_reloaded->stcr->update_subscription_email( $post_id, $old_email, $new_email ); 97 | 98 | echo '

' . esc_html__( 'Subscriptions updated.', 'subscribe-to-comments-reloaded' ) . '

'; 99 | break; 100 | 101 | case 'delete-subscription': 102 | 103 | if ( empty( $_GET['stcr_delete_subscription_nonce'] ) ) { 104 | exit(); 105 | } 106 | 107 | if ( ! wp_verify_nonce( $_GET['stcr_delete_subscription_nonce'], 'stcr_delete_subscription_nonce' ) ) { 108 | exit(); 109 | } 110 | 111 | if ( ! current_user_can( 'manage_options' ) ) { 112 | exit(); 113 | } 114 | 115 | $stcr_post_email = $wp_subscribe_reloaded->stcr->utils->check_valid_email( $stcr_post_email ); 116 | $valid_post_id = $wp_subscribe_reloaded->stcr->utils->check_valid_number( $post_id ); 117 | 118 | if ( $stcr_post_email === false ) 119 | { 120 | $valid_email = false; 121 | break; 122 | } 123 | 124 | $wp_subscribe_reloaded->stcr->delete_subscriptions( $post_id, $stcr_post_email ); 125 | 126 | echo '

' . esc_html__( 'Subscription deleted.', 'subscribe-to-comments-reloaded' ) . '

'; 127 | break; 128 | 129 | default: 130 | if ( ! empty( $_POST['subscriptions_list'] ) ) { 131 | 132 | if ( empty( $_POST['stcr_update_subscriptions_nonce'] ) ) { 133 | exit(); 134 | } 135 | 136 | if ( ! wp_verify_nonce( $_POST['stcr_update_subscriptions_nonce'], 'stcr_update_subscriptions_nonce' ) ) { 137 | exit(); 138 | } 139 | 140 | if ( ! current_user_can( 'manage_options' ) ) { 141 | exit(); 142 | } 143 | 144 | $post_list = $email_list = array(); 145 | $subscription_lists = wp_unslash( $_POST['subscriptions_list'] ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput 146 | $subscription_lists = array_map( 'wp_kses_post', $subscription_lists ); 147 | foreach ( $subscription_lists as $a_subscription ) { 148 | list( $a_post, $a_email ) = explode( ',', $a_subscription ); 149 | if ( ! in_array( $a_post, $post_list ) ) { 150 | $post_list[] = $a_post; 151 | } 152 | if ( ! in_array( $a_email, $email_list ) ) { 153 | $email_list[] = urldecode( $a_email ); 154 | } 155 | } 156 | 157 | switch ( $action ) { 158 | case 'delete': 159 | $rows_affected = $wp_subscribe_reloaded->stcr->delete_subscriptions( $post_list, $email_list ); 160 | echo '

' . esc_html__( 'Subscriptions deleted:', 'subscribe-to-comments-reloaded' ) . esc_html( $rows_affected ) . '

'; 161 | break; 162 | case 'suspend': 163 | $rows_affected = $wp_subscribe_reloaded->stcr->update_subscription_status( $post_list, $email_list, 'C' ); 164 | echo '

' . esc_html__( 'Subscriptions suspended:', 'subscribe-to-comments-reloaded' ) . esc_html( $rows_affected ) . '

'; 165 | break; 166 | case 'activate': 167 | $rows_affected = $wp_subscribe_reloaded->stcr->update_subscription_status( $post_list, $email_list, '-C' ); 168 | echo '

' . esc_html__( 'Subscriptions activated:', 'subscribe-to-comments-reloaded' ) . esc_html( $rows_affected ) . '

'; 169 | break; 170 | case 'force_y': 171 | $rows_affected = $wp_subscribe_reloaded->stcr->update_subscription_status( $post_list, $email_list, 'Y' ); 172 | echo '

' . esc_html__( 'Subscriptions updated:', 'subscribe-to-comments-reloaded' ) . esc_html( $rows_affected ) . '

'; 173 | break; 174 | case 'force_r': 175 | $rows_affected = $wp_subscribe_reloaded->stcr->update_subscription_status( $post_list, $email_list, 'R' ); 176 | echo '

' . esc_html__( 'Subscriptions updated:', 'subscribe-to-comments-reloaded' ) . esc_html( $rows_affected ) . '

'; 177 | break; 178 | default: 179 | break; 180 | } 181 | } 182 | } 183 | 184 | $initial_limit_results = 1000; 185 | $official_limit_results = '18446744073709551610'; 186 | 187 | $search_field = ! empty( $_POST['srf'] ) ? sanitize_text_field( wp_unslash( $_POST['srf'] ) ) : ( ! empty( $_GET['srf'] ) ? sanitize_text_field( wp_unslash( $_GET['srf'] ) ) : 'email' ); 188 | $operator = ! empty( $_POST['srt'] ) ? sanitize_text_field( wp_unslash( $_POST['srt'] ) ) : ( ! empty( $_GET['srt'] ) ? sanitize_text_field( wp_unslash( $_GET['srt'] ) ) : 'contains' ); 189 | $search_value = ! empty( $_POST['srv'] ) ? sanitize_text_field( wp_unslash( $_POST['srv'] ) ) : ( ! empty( $_GET['srv'] ) ? sanitize_text_field( wp_unslash( $_GET['srv'] ) ) : '@' ); 190 | $order_by = ! empty( $_POST['srob'] ) ? sanitize_text_field( wp_unslash( $_POST['srob'] ) ) : ( ! empty( $_GET['srob'] ) ? sanitize_text_field( wp_unslash( $_GET['srob'] ) ) : 'dt' ); 191 | $order = ! empty( $_POST['sro'] ) ? sanitize_text_field( wp_unslash( $_POST['sro'] ) ) : ( ! empty( $_GET['sro'] ) ? sanitize_text_field( wp_unslash( $_GET['sro'] ) ) : 'DESC' ); 192 | $offset = ! empty( $_POST['srsf'] ) ? intval( $_POST['srsf'] ) : ( ! empty( $_GET['srsf'] ) ? intval( $_GET['srsf'] ) : 0 ); 193 | $limit_results = ! empty( $_POST['srrp'] ) ? intval( $_POST['srrp'] ) : ( ! empty( $_GET['srrp'] ) ? intval( $_GET['srrp'] ) : $initial_limit_results ); 194 | 195 | $subscriptions = $wp_subscribe_reloaded->stcr->get_subscriptions( $search_field, $operator, $search_value, $order_by, $order, $offset, $limit_results ); 196 | $count_total = count( $wp_subscribe_reloaded->stcr->get_subscriptions( $search_field, $operator, $search_value ) ); 197 | 198 | $count_results = count( $subscriptions ); // 0 if $results is null 199 | $ending_to = min( $count_total, $offset + $limit_results ); 200 | $previous_link = $next_link = $next_page_link = $previous_page_link = ''; 201 | 202 | if ( $offset > 0 ) { 203 | $new_starting = ( $offset > $limit_results ) ? $offset - $limit_results : 0; 204 | $previous_link = "" . esc_html__( '« Previous', 'subscribe-to-comments-reloaded' ) . " "; 205 | } 206 | if ( ( $ending_to < $count_total ) && ( $count_results > 0 ) ) { 207 | $new_starting = $offset + $limit_results; 208 | $next_link = "" . esc_html__( 'Next »', 'subscribe-to-comments-reloaded' ) . " "; 209 | } 210 | -------------------------------------------------------------------------------- /src/options/panel1-edit-subscription.php: -------------------------------------------------------------------------------- 1 | 7 |
8 |

9 | 10 |
12 |
13 |

14 | ' . esc_html( get_the_title( intval( $_GET['srp'] ) ) ) . ' (' . intval( $_GET['srp'] ) . ')'; 17 | ?> 18 |

19 | 20 |

21 | 22 | 23 |

24 | 25 |

26 | ' style="color:#ccc" 27 | onfocus='if (this.value == "") this.value="";this.style.color="#000"' 28 | onblur='if (this.value == ""){this.value="";this.style.color="#ccc"}' /> 29 |

30 | 31 |

32 | 38 | ' /> 39 |

40 | 41 | ' /> 42 | 43 |
44 |
45 |
46 | -------------------------------------------------------------------------------- /src/options/stcr_support.php: -------------------------------------------------------------------------------- 1 | 12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 | 20 |
21 |

Subscribe to Comments Reloaded and so on. Whatever you do, thanks for using my plugin!", 'subscribe-to-comments-reloaded' ), wp_kses_allowed_html( 'post' ) ); ?>

22 | 23 |
24 |

here", 'subscribe-to-comments-reloaded' ), wp_kses_allowed_html( 'post' ) ); ?>

25 | 26 |
27 |

Subscribe to Comments Reloaded works for you and how good it is. Rate it on its Plugin Directory page.', 'subscribe-to-comments-reloaded' ), wp_kses_allowed_html( 'post' ) ); ?>

28 | 29 |
30 |

GitHub Page rather than on the WordPress Support page.', 'subscribe-to-comments-reloaded' ), wp_kses_allowed_html( 'post' ) ); ?> 31 |

32 | 36 |
37 |
38 | 39 |
40 |
41 | 42 |
43 |
44 |
45 |

46 | Thank you for using Subscribe to Comments Reloaded. You can Support the plugin by rating it 47 | Rate Subscribe to Comments Reloaded 48 |

49 |

50 | Having issues? Please create a ticket 51 |

52 |
53 |
54 |
55 | 56 |
57 |
58 | -------------------------------------------------------------------------------- /src/post-and-comments.css: -------------------------------------------------------------------------------- 1 | table.comments-box.fixed { 2 | table-layout: auto; 3 | } 4 | 5 | table.comments-box.fixed #the-comment-list td.column-author { 6 | width: 30%; 7 | } 8 | 9 | th.column-subscribe-reloaded, td.column-subscribe-reloaded { 10 | text-align: center; 11 | width: 5%; 12 | } -------------------------------------------------------------------------------- /src/style.css: -------------------------------------------------------------------------------- 1 | #subscribe-to-comments-icon { 2 | background-image: url(images/subscribe-to-comments.png); 3 | background-position: center; 4 | background-repeat: no-repeat; 5 | margin: 8px 6px 0 4px; 6 | } 7 | 8 | #subscribe-to-comments-icon.rtl { 9 | float: right; 10 | } 11 | 12 | .wrap h2.medium { 13 | border-bottom: 1px solid #CCCCCC; 14 | font-size: .9em; 15 | padding-bottom: 0; 16 | } 17 | 18 | .wrap .nav-tab { 19 | /*border-style: dashed;*/ 20 | color: #464646; 21 | font-size: 1em; 22 | font-style: normal; 23 | line-height: 1.1em; 24 | padding: 10px; 25 | text-decoration: none; 26 | } 27 | 28 | .wrap a.nav-tab.nav-tab-inactive:hover { 29 | background-color: #fff; 30 | } 31 | 32 | .wrap .nav-tab.nav-tab-active { 33 | border-style: solid; 34 | font-weight: 700; 35 | position: relative; 36 | } 37 | 38 | .donate-tab { 39 | background-color: #FEE0A5; 40 | color: #003366 !important; 41 | border: 1px solid #FF9933; 42 | font-weight: bold !important; 43 | font-size: 14px !important; 44 | } 45 | 46 | .donate-tab-active { 47 | background-color: #faf2c8 !important; 48 | border-bottom: none !important; 49 | } 50 | 51 | .donate-tab:hover { 52 | background-color: #faf2c8 !important; 53 | } 54 | 55 | .wrap div.updated { 56 | width: 97.2%; 57 | } 58 | 59 | 60 | 61 | .postbox { 62 | float: left; 63 | margin-right: 5px; 64 | /*overflow: auto;*/ 65 | width: 98.6%; 66 | 67 | } 68 | 69 | .postbox.small { 70 | margin-top: 10px; 71 | width: 49%; 72 | } 73 | 74 | .postbox h3, .postbox p, .postbox ul { 75 | cursor: default; 76 | font-size: .9em; 77 | margin: 0; 78 | padding: 4px; 79 | } 80 | 81 | .postbox p.liquid { 82 | float: left; 83 | } 84 | 85 | .postbox span.right { 86 | float: right; 87 | } 88 | 89 | .postbox p.small { 90 | font-size: .8em; 91 | } 92 | 93 | .postbox .subscribe-list-navigation { 94 | float: right; 95 | font-size: .8em; 96 | } 97 | 98 | .postbox .subscribe-list-navigation a { 99 | margin-right: 10px; 100 | } 101 | 102 | .postbox .subscribe-list-header { 103 | background-color: #dfdfdf; 104 | } 105 | 106 | .postbox .subscribe-column { 107 | float: left; 108 | padding-right: 6px; 109 | } 110 | 111 | .postbox .subscribe-column-1 { 112 | min-width: 35%; 113 | } 114 | 115 | .postbox .subscribe-column-2 { 116 | min-width: 25%; 117 | } 118 | 119 | .postbox .subscribe-column-3 { 120 | min-width: 20%; 121 | } 122 | 123 | .postbox .subscribe-column-4 { 124 | min-width: 5%; 125 | text-align: center; 126 | } 127 | 128 | .postbox ul li { 129 | margin-bottom: 0; 130 | overflow: auto; 131 | padding: 3px 0; 132 | } 133 | 134 | input.checkbox { 135 | float: left; 136 | margin: 2px 12px 0 5px; 137 | } 138 | 139 | .form-table th, 140 | .form-table td { 141 | padding: 3px 10px; 142 | } 143 | 144 | .form-table td.description { 145 | white-space: normal; 146 | } 147 | 148 | .form-table td.narrowcolumn { 149 | width: 100px; 150 | } 151 | 152 | .form-table td.shortrow { 153 | padding: 0 10px 20px; 154 | white-space: normal; 155 | } 156 | 157 | .form-table input { 158 | margin: 0 8px 0 0; 159 | } 160 | 161 | .form-table.rtl input { 162 | margin: 0 0 0 8px; 163 | } 164 | 165 | .form-table input.longtext { 166 | width: 400px; 167 | } 168 | 169 | .form-table textarea { 170 | width: 90%; 171 | } 172 | 173 | 174 | .clearFix { 175 | clear: both; 176 | } 177 | 178 | .stcr-active-tab { 179 | border-bottom: 4px solid #ffc53a; 180 | } -------------------------------------------------------------------------------- /src/subscribe-to-comments-reloaded.php: -------------------------------------------------------------------------------- 1 | stcr = new wp_subscribe_reloaded(); 49 | $this->stcr->set_user_cookie(); 50 | } 51 | 52 | /** 53 | * This will trigger the activate function located on utils/stcr_manage.php 54 | * 55 | * @since 150720 56 | */ 57 | static function activate() { 58 | require_once dirname( STCR_PLUGIN_FILE ) . '/utils/stcr_manage.php'; 59 | $_stcra = new stcr_manage(); 60 | $_stcra->activate(); 61 | } 62 | 63 | /** 64 | * This will trigger the deactivate function located on utils/stcr_manage.php 65 | * 66 | * @since 150720 67 | */ 68 | static function deactivate() { 69 | require_once dirname( STCR_PLUGIN_FILE ) . '/utils/stcr_manage.php'; 70 | $_stcrd = new stcr_manage(); 71 | $_stcrd->deactivate(); 72 | } 73 | 74 | } 75 | 76 | // plugin activation 77 | register_activation_hook( STCR_PLUGIN_FILE, array( \stcr\stcr_subscribe_reloaded::CLASSNAME , 'activate' ) ); 78 | 79 | // plugin deactivation 80 | register_deactivation_hook( STCR_PLUGIN_FILE, array( \stcr\stcr_subscribe_reloaded::CLASSNAME , 'deactivate' ) ); 81 | 82 | // instantiate stcr_subscribe_reloaded class 83 | if ( ! isset( $GLOBALS['wp_subscribe_reloaded'] ) ) { 84 | $GLOBALS['wp_subscribe_reloaded'] = new stcr_subscribe_reloaded(); 85 | } 86 | 87 | } 88 | -------------------------------------------------------------------------------- /src/templates/author.php: -------------------------------------------------------------------------------- 1 | stcr->delete_subscriptions( $post_ID, $email_list ); 38 | echo '

' . esc_html__( 'Subscriptions deleted:', 'subscribe-to-comments-reloaded' ) . esc_html( $rows_affected ) . '

'; 39 | break; 40 | case 'suspend': 41 | $rows_affected = $wp_subscribe_reloaded->stcr->update_subscription_status( $post_ID, $email_list, 'C' ); 42 | echo '

' . esc_html__( 'Subscriptions suspended:', 'subscribe-to-comments-reloaded' ) . esc_html( $rows_affected ) . '

'; 43 | break; 44 | case 'activate': 45 | $rows_affected = $wp_subscribe_reloaded->stcr->update_subscription_status( $post_ID, $email_list, '-C' ); 46 | echo '

' . esc_html__( 'Subscriptions activated:', 'subscribe-to-comments-reloaded' ) . esc_html( $rows_affected ) . '

'; 47 | break; 48 | case 'force_y': 49 | $rows_affected = $wp_subscribe_reloaded->stcr->update_subscription_status( $post_ID, $email_list, 'Y' ); 50 | echo '

' . esc_html__( 'Subscriptions updated:', 'subscribe-to-comments-reloaded' ) . esc_html( $rows_affected ) . '

'; 51 | break; 52 | case 'force_r': 53 | $rows_affected = $wp_subscribe_reloaded->stcr->update_subscription_status( $post_ID, $email_list, 'R' ); 54 | echo '

' . esc_html__( 'Subscriptions updated:', 'subscribe-to-comments-reloaded' ) . esc_html( $rows_affected ) . '

'; 55 | break; 56 | default: 57 | break; 58 | } 59 | } 60 | $message = html_entity_decode( stripslashes( get_option( 'subscribe_reloaded_author_text' ) ), ENT_QUOTES, 'UTF-8' ); 61 | if ( function_exists( 'qtrans_useCurrentLanguageIfNotFoundUseDefaultLanguage' ) ) { 62 | $message = qtrans_useCurrentLanguageIfNotFoundUseDefaultLanguage( $message ); 63 | } 64 | echo "

" . wp_kses( $message, wp_kses_allowed_html( 'post' ) ) . "

"; 65 | ?> 66 | 67 | 68 |
69 |
70 | stcr->get_subscriptions( 'post_id', 'equals', $post_ID, 'dt', 'ASC' ); 72 | // Let us translate those status 73 | $legend_translate = array( 74 | 'R' => esc_html__( 'Replies', 'subscribe-to-comments-reloaded'), 75 | 'RC' => esc_html__( 'Replies Unconfirmed', 'subscribe-to-comments-reloaded'), 76 | 'Y' => esc_html__( "All Comments", 'subscribe-to-comments-reloaded'), 77 | 'YC' => esc_html__( "Unconfirmed", 'subscribe-to-comments-reloaded'), 78 | 'C' => esc_html__( "Inactive", 'subscribe-to-comments-reloaded'), 79 | '-C' => esc_html__( "Active", 'subscribe-to-comments-reloaded') 80 | ); 81 | if ( is_array( $subscriptions ) && ! empty( $subscriptions ) ) { 82 | $total_subscriptions = count( $subscriptions ); 83 | $subscriptions_per_page = 200; 84 | $subscriptions_total_pages = ceil( $total_subscriptions / $subscriptions_per_page ); 85 | $subscriptions_pagenum = isset( $_REQUEST['subscription_paged'] ) ? absint( $_REQUEST['subscription_paged'] ) : 1; // phpcs:ignore WordPress.Security.NonceVerification.Recommended 86 | $subscriptions_offset = ( $subscriptions_pagenum - 1 ) * $subscriptions_per_page; 87 | $subscriptions = array_slice( $subscriptions, $subscriptions_offset, $subscriptions_per_page ); 88 | 89 | $disable_first = false; 90 | $disable_last = false; 91 | $disable_prev = false; 92 | $disable_next = false; 93 | 94 | if ( 1 == $subscriptions_pagenum ) { // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison 95 | $disable_first = true; 96 | $disable_prev = true; 97 | } 98 | 99 | if ( $subscriptions_total_pages == $subscriptions_pagenum ) { // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison 100 | $disable_last = true; 101 | $disable_next = true; 102 | } 103 | 104 | // For generating new url. 105 | $removable_query_args = array( 'post_permalink' ); 106 | $server_http_host = isset( $_SERVER['HTTP_HOST'] ) ? sanitize_text_field( wp_unslash( $_SERVER['HTTP_HOST'] ) ) : ''; 107 | $server_request_uri = isset( $_SERVER['REQUEST_URI'] ) ? sanitize_text_field( wp_unslash( $_SERVER['REQUEST_URI'] ) ) : ''; 108 | $current_url = set_url_scheme( 'http://' . $server_http_host . $server_request_uri ); 109 | $current_url = remove_query_arg( $removable_query_args, $current_url ); 110 | 111 | echo '

' . esc_html__( 'Title', 'subscribe-to-comments-reloaded' ) . ': ' . esc_html( $target_post->post_title ) . '

'; // $target_post comes from wp_subscribe_reloaded\subscribe_reloaded_manage 112 | 113 | echo " 114 | 115 | 116 | 117 | "; 118 | echo ""; 119 | 120 | foreach ( $subscriptions as $i => $a_subscription ) { 121 | $t_status = $a_subscription->status; 122 | $date = strtotime( $a_subscription->dt ); 123 | $formatted_date = date( get_option( "subscribe_reloaded_date_format" ), $date ); 124 | $date_translated = $wp_subscribe_reloaded->stcr->utils->stcr_translate_month( $formatted_date ); 125 | 126 | echo ""; 127 | echo ""; 128 | echo ""; 129 | echo ""; 130 | echo ""; 131 | } 132 | echo ""; 133 | echo "
  ". esc_html__('Subscription Date','subscribe-to-comments-reloaded')."  ". esc_html__('Subscription Email','subscribe-to-comments-reloaded')."   ". esc_html__('Subscription Status','subscribe-to-comments-reloaded')."
". esc_html( $a_subscription->email ) . "" . esc_html( $legend_translate[ $t_status ] ) . "
"; 134 | ?> 135 | 136 | 1 ) { ?> 137 | 208 | 209 | 210 |   '; 212 | echo '   

'; 213 | echo '

' . esc_html__( 'Action:', 'subscribe-to-comments-reloaded' ); 214 | echo '  '; 222 | echo '   223 |

'; 224 | echo '

225 |  '. esc_html__('Return to Post','subscribe-to-comments-reloaded').' 226 |

'; 227 | 228 | 229 | } else { 230 | echo '

' . esc_html__( 'No subscriptions match your search criteria.', 'subscribe-to-comments-reloaded' ) . '

'; 231 | } 232 | ?> 233 |
234 |
235 | 236 | 265 | 270 | -------------------------------------------------------------------------------- /src/templates/confirm.php: -------------------------------------------------------------------------------- 1 | stcr->update_subscription_status( $post_ID, $email, '-C' ); 26 | 27 | // get confirmed message 28 | $message = html_entity_decode( stripslashes( get_option( 'subscribe_reloaded_subscription_confirmed' ) ), ENT_COMPAT, 'UTF-8' ); 29 | 30 | // qTranslate compatibility 31 | if ( function_exists( 'qtrans_useCurrentLanguageIfNotFoundUseDefaultLanguage' ) ) { 32 | $message = qtrans_useCurrentLanguageIfNotFoundUseDefaultLanguage( $message ); 33 | } 34 | 35 | // append post link to message 36 | if ( isset( $post_permalink ) ) { 37 | $message .= '

38 |   '. esc_html__('Return to Post','subscribe-to-comments-reloaded').' 39 |

'; 40 | } 41 | 42 | // pass it back 43 | return '
' . $message . '
'; 44 | -------------------------------------------------------------------------------- /src/templates/key_expired.php: -------------------------------------------------------------------------------- 1 | stcr->utils->clean_email( $email ); 26 | $subscriber_salt = $wp_subscribe_reloaded->stcr->utils->generate_temp_key( $clean_email ); 27 | 28 | $manager_link .= ( strpos( $manager_link, '?' ) !== false ) ? '&' : '?'; 29 | $manager_link .= "srek=" . $wp_subscribe_reloaded->stcr->utils->get_subscriber_key($clean_email) . "&srk=$subscriber_salt&srsrc=e"; 30 | $one_click_unsubscribe_link .= ( strpos( $one_click_unsubscribe_link, '?' ) !== false ) ? '&' : '?'; 31 | $one_click_unsubscribe_link .= ( ( strpos( $one_click_unsubscribe_link, '?' ) !== false ) ? '&' : '?' ) . "srek=" . $this->utils->get_subscriber_key( $clean_email ) . "&srk=$subscriber_salt" . "&sra=u" . "&srp="; 32 | 33 | // Replace tags with their actual values 34 | $subject = str_replace( '[blog_name]', get_bloginfo( 'name' ), $subject ); 35 | // Setup the fronted page message 36 | $page_message = str_replace( '[blog_name]', get_bloginfo( 'name' ), $page_message ); 37 | // Setup the email message 38 | $email_message = str_replace( '[blog_name]', get_bloginfo( 'name' ), $email_message ); 39 | $email_message = str_replace( '[manager_link]', $manager_link, $email_message ); 40 | $email_message = str_replace( '[oneclick_link]', $one_click_unsubscribe_link, $email_message ); 41 | 42 | if ( get_option( 'subscribe_reloaded_enable_html_emails', 'yes' ) == 'yes' ) { 43 | $email_message = wpautop( $email_message ); 44 | } 45 | 46 | // QTranslate support 47 | if ( function_exists( 'qtrans_useCurrentLanguageIfNotFoundUseDefaultLanguage' ) ) { 48 | $subject = qtrans_useCurrentLanguageIfNotFoundUseDefaultLanguage( $subject ); 49 | $page_message = qtrans_useCurrentLanguageIfNotFoundUseDefaultLanguage( $page_message ); 50 | $email_message = qtrans_useCurrentLanguageIfNotFoundUseDefaultLanguage( $email_message ); 51 | } 52 | // Prepare email settings 53 | $email_settings = array( 54 | 'subject' => $subject, 55 | 'message' => $email_message, 56 | 'toEmail' => $clean_email 57 | ); 58 | $has_blacklist_email = $this->utils->blacklisted_emails( $clean_email ); 59 | // Send the confirmation email only if the email 60 | // address is not in blacklist email list. 61 | if ( $has_blacklist_email ) { 62 | $wp_subscribe_reloaded->stcr->utils->send_email( $email_settings ); 63 | } 64 | 65 | echo wpautop( wp_kses( $page_message, wp_kses_allowed_html( 'post' ) ) ); 66 | } 67 | else 68 | { 69 | $message = html_entity_decode( stripslashes( get_option( 'subscribe_reloaded_request_mgmt_link' ) ), ENT_QUOTES, 'UTF-8' ); 70 | if ( function_exists( 'qtrans_useCurrentLanguageIfNotFoundUseDefaultLanguage' ) ) { 71 | $message = qtrans_useCurrentLanguageIfNotFoundUseDefaultLanguage( $message ); 72 | } 73 | ?> 74 | 75 |
" name="sub-form" method="post"> 80 |
81 |

82 | 85 | 86 | 87 |

88 |
89 |
90 | 96 | -------------------------------------------------------------------------------- /src/templates/not-allowed.php: -------------------------------------------------------------------------------- 1 | 21 | -------------------------------------------------------------------------------- /src/templates/one-click-unsubscribe.php: -------------------------------------------------------------------------------- 1 | stcr->delete_subscriptions( $post_ID, $email ); 23 | 24 | if ( function_exists( 'qtrans_useCurrentLanguageIfNotFoundUseDefaultLanguage' ) ) { 25 | $message = qtrans_useCurrentLanguageIfNotFoundUseDefaultLanguage( $message ); 26 | } 27 | $message = wpautop( $message ); // Let us add the

tag if need it. 28 | echo wp_kses( $message, wp_kses_allowed_html( 'post' ) ); // TODO: Add management link with number of subscriptions. 29 | } else { 30 | echo '

' . esc_html__( 'No subscriptions match your search criteria.', 'subscribe-to-comments-reloaded' ) . '

'; 31 | } 32 | $output = ob_get_contents(); 33 | ob_end_clean(); 34 | 35 | return $output; 36 | ?> 37 | -------------------------------------------------------------------------------- /src/templates/request-management-link.php: -------------------------------------------------------------------------------- 1 | '; 31 | if ( isset( $_POST['g-recaptcha-response'] ) ) { 32 | $captcha = sanitize_text_field( wp_unslash( $_POST['g-recaptcha-response'] ) ); 33 | $captcha_result = wp_remote_post( 'https://www.google.com/recaptcha/api/siteverify', array( 34 | 'method' => 'POST', 35 | 'body' => array( 36 | 'secret' => $captcha_secret_key, 37 | 'response' => $captcha, 38 | ) 39 | )); 40 | if ( is_wp_error( $captcha_result ) ) { 41 | $valid_captcha = false; 42 | } else { 43 | $captcha_response = json_decode( $captcha_result['body'], true ); 44 | if ( ! $captcha_response['success'] ) { 45 | $valid_captcha = false; 46 | } 47 | } 48 | } else { 49 | $valid_captcha = false; 50 | } 51 | } elseif ( 'v3' == $recaptcha_version ) { 52 | if ( isset( $_POST['token'] ) ) { 53 | $captcha = sanitize_text_field( wp_unslash( $_POST['token'] ) ); 54 | $action = sanitize_text_field( wp_unslash( $_POST['action'] ) ); 55 | 56 | $captcha_result = wp_remote_post( 'https://www.google.com/recaptcha/api/siteverify', array( 57 | 'method' => 'POST', 58 | 'body' => array( 59 | 'secret' => $captcha_secret_key, 60 | 'response' => $captcha, 61 | ) 62 | )); 63 | if ( is_wp_error( $captcha_result ) ) { 64 | $valid_captcha = false; 65 | } else { 66 | $captcha_response = json_decode( $captcha_result['body'], true ); 67 | if ( ! $captcha_response['success'] || ! $captcha_response['action'] == $action || $captcha_response['score'] < 0.5 ) { 68 | $valid_captcha = false; 69 | } 70 | } 71 | } else { 72 | $valid_captcha = false; 73 | } 74 | } else { 75 | $valid_captcha = false; 76 | } 77 | } 78 | 79 | // get email if user known 80 | if ( isset( $current_user ) && $current_user->ID > 0 ) { 81 | $current_user_email = $current_user->data->user_email; 82 | } 83 | 84 | // post permalink supplied with $_GET 85 | if ( array_key_exists('post_permalink', $_GET ) ) { 86 | if ( ! empty( $_GET['post_permalink'] ) ) { 87 | $post_permalink = sanitize_text_field( wp_unslash( $_GET['post_permalink'] ) ); 88 | } 89 | } 90 | 91 | if ( strpos( $post_permalink, home_url( '/' ) ) === false ) { 92 | $post_permalink = home_url( '/' ); 93 | } 94 | 95 | // challenge question 96 | $challenge_question_state = get_option( 'subscribe_reloaded_use_challenge_question', 'no' ); 97 | $challenge_question = get_option( 'subscribe_reloaded_challenge_question', 'What is 1 + 2?' ); 98 | $challenge_answer = get_option( 'subscribe_reloaded_challenge_answer', '3' ); 99 | 100 | // start output buffering 101 | ob_start(); 102 | 103 | // email address supplied 104 | if ( ! empty( $email ) ) { 105 | 106 | // check email validity 107 | $stcr_post_email = $wp_subscribe_reloaded->stcr->utils->check_valid_email( $email ); 108 | 109 | // check challenge question validity 110 | if ( $challenge_question_state == 'yes' ) { 111 | $challenge_user_answer = sanitize_text_field( $_POST['subscribe_reloaded_challenge'] ); 112 | if ( $challenge_answer != $challenge_user_answer ) { 113 | $valid_challenge = false; 114 | $valid_all = false; 115 | } 116 | } 117 | 118 | // email is invalid 119 | if ( $stcr_post_email === false ) { 120 | $valid_email = false; 121 | $valid_all = false; 122 | } 123 | 124 | // email is not subscribed 125 | if ( ! $wp_subscribe_reloaded->stcr->utils->get_subscriber_key( $stcr_post_email ) ) { 126 | $valid_email = false; 127 | $valid_all = false; 128 | } 129 | 130 | // captcha is not valid 131 | if ( ! $valid_captcha ) { 132 | $valid_all = false; 133 | } 134 | 135 | if ( $valid_all ) { 136 | 137 | // Send management link 138 | $subject = html_entity_decode( stripslashes( get_option( 'subscribe_reloaded_management_subject', 'Manage your subscriptions on [blog_name]' ) ), ENT_QUOTES, 'UTF-8' ); 139 | $page_message = html_entity_decode( stripslashes( get_option( 'subscribe_reloaded_management_content', '' ) ), ENT_QUOTES, 'UTF-8' ); 140 | $email_message = html_entity_decode( stripslashes( get_option( 'subscribe_reloaded_management_email_content', '' ) ), ENT_QUOTES, 'UTF-8' ); 141 | $manager_link = get_bloginfo( 'url' ) . get_option( 'subscribe_reloaded_manager_page', '/comment-subscriptions/' ); 142 | $one_click_unsubscribe_link = $manager_link; 143 | if ( function_exists( 'qtrans_convertURL' ) ) { 144 | $manager_link = qtrans_convertURL( $manager_link ); 145 | } 146 | 147 | $clean_email = $wp_subscribe_reloaded->stcr->utils->clean_email( $email ); 148 | $subscriber_salt = $wp_subscribe_reloaded->stcr->utils->generate_temp_key( $clean_email ); 149 | 150 | $manager_link .= ( strpos( $manager_link, '?' ) !== false ) ? '&' : '?'; 151 | $manager_link .= "srek=" . $wp_subscribe_reloaded->stcr->utils->get_subscriber_key($clean_email) . "&srk=$subscriber_salt&srsrc=e&post_permalink=" . esc_url( $post_permalink ); 152 | $one_click_unsubscribe_link .= ( strpos( $one_click_unsubscribe_link, '?' ) !== false ) ? '&' : '?'; 153 | $one_click_unsubscribe_link .= ( ( strpos( $one_click_unsubscribe_link, '?' ) !== false ) ? '&' : '?' ) 154 | . "srek=" . esc_attr( $this->utils->get_subscriber_key( $clean_email ) ) 155 | . "&srk=$subscriber_salt" . "&sra=u;srsrc=e" . "&srp="; 156 | 157 | // Replace tags with their actual values 158 | $subject = str_replace( '[blog_name]', get_bloginfo( 'name' ), $subject ); 159 | $page_message = str_replace( '[blog_name]', get_bloginfo( 'name' ), $page_message ); 160 | $email_message = str_replace( '[blog_name]', get_bloginfo( 'name' ), $email_message ); 161 | $email_message = str_replace( '[manager_link]', $manager_link, $email_message ); 162 | $email_message = str_replace( '[oneclick_link]', $one_click_unsubscribe_link, $email_message ); 163 | 164 | if ( get_option( 'subscribe_reloaded_enable_html_emails', 'yes' ) == 'yes' ) { 165 | $email_message = wpautop( $email_message ); 166 | } 167 | 168 | // QTranslate support 169 | if ( function_exists( 'qtrans_useCurrentLanguageIfNotFoundUseDefaultLanguage' ) ) { 170 | $subject = qtrans_useCurrentLanguageIfNotFoundUseDefaultLanguage( $subject ); 171 | $page_message = qtrans_useCurrentLanguageIfNotFoundUseDefaultLanguage( $page_message ); 172 | $email_message = qtrans_useCurrentLanguageIfNotFoundUseDefaultLanguage( $email_message ); 173 | } 174 | 175 | // Prepare email settings 176 | $email_settings = array( 177 | 'subject' => $subject, 178 | 'message' => $email_message, 179 | 'toEmail' => $clean_email 180 | ); 181 | 182 | $has_blacklist_email = $this->utils->blacklisted_emails( $clean_email ); 183 | // Send the confirmation email only if the email 184 | // address is not in blacklist email list. 185 | if ( $has_blacklist_email ) { 186 | $wp_subscribe_reloaded->stcr->utils->send_email( $email_settings ); 187 | } 188 | 189 | echo wp_kses( wpautop( $page_message ), wp_kses_allowed_html( 'post' ) ); 190 | 191 | } 192 | 193 | // email address not supplied 194 | } else { 195 | 196 | $message = html_entity_decode( stripslashes( get_option( 'subscribe_reloaded_request_mgmt_link' ) ), ENT_QUOTES, 'UTF-8' ); 197 | 198 | // get email address 199 | $email = ''; 200 | if ( isset($current_user_email) ) { 201 | $email = $current_user_email; 202 | } else if ( isset( $_COOKIE['comment_author_email_' . COOKIEHASH] )) { 203 | $email = sanitize_email( wp_unslash( $_COOKIE[ 'comment_author_email_' . COOKIEHASH ] ) ); 204 | } else { 205 | $email = ''; 206 | } 207 | 208 | // qTrans compatibility 209 | if ( function_exists( 'qtrans_useCurrentLanguageIfNotFoundUseDefaultLanguage' ) ) { 210 | $message = qtrans_useCurrentLanguageIfNotFoundUseDefaultLanguage( $message ); 211 | } 212 | 213 | ?> 214 | 215 | 216 |
217 |
218 | 219 |

220 | 221 | 222 |

223 |

224 | 225 | 226 |

227 |

228 | 229 |

230 | 231 | 232 | 233 |

234 | 235 | 236 | 237 |

238 | 239 | 240 | 241 | 242 |
243 |
244 | 248 |   '. esc_html__('Return to Post','subscribe-to-comments-reloaded').' 249 |

'; 250 | } 251 | 252 | } 253 | 254 | if ( $use_captcha == 'yes' && $valid_captcha && 'v3' == $recaptcha_version ) { 255 | ?> 256 |
257 | 258 | 277 |
278 | 291 | 292 | 293 |
294 |
295 | 296 | 297 |

298 | 299 | 300 |

301 |

302 | 303 | 304 |

305 |

306 | 307 |

308 | 309 |

310 | 311 |

312 | 313 | 314 | 315 |

316 | 317 |

318 | 319 | 320 | 321 |

322 | 323 | 324 | 325 |

326 | 327 | 328 | 329 |

330 | 331 | 332 |
333 |
334 | 342 | -------------------------------------------------------------------------------- /src/templates/subscribe.php: -------------------------------------------------------------------------------- 1 | '; 32 | if ( isset( $_POST['g-recaptcha-response'] ) ) { 33 | $captcha = sanitize_text_field( wp_unslash( $_POST['g-recaptcha-response'] ) ); 34 | $captcha_result = wp_remote_post( 'https://www.google.com/recaptcha/api/siteverify', array( 35 | 'method' => 'POST', 36 | 'body' => array( 37 | 'secret' => $captcha_secret_key, 38 | 'response' => $captcha, 39 | ) 40 | )); 41 | if ( is_wp_error( $captcha_result ) ) { 42 | $valid_captcha = false; 43 | } else { 44 | $captcha_response = json_decode( $captcha_result['body'], true ); 45 | if ( ! $captcha_response['success'] ) { 46 | $valid_captcha = false; 47 | } 48 | } 49 | } 50 | } elseif ( 'v3' == $recaptcha_version ) { 51 | if ( isset( $_POST['token'] ) ) { 52 | $captcha = sanitize_text_field( wp_unslash( $_POST['token'] ) ); 53 | $action = sanitize_text_field( wp_unslash( $_POST['action'] ) ); 54 | 55 | $captcha_result = wp_remote_post( 'https://www.google.com/recaptcha/api/siteverify', array( 56 | 'method' => 'POST', 57 | 'body' => array( 58 | 'secret' => $captcha_secret_key, 59 | 'response' => $captcha, 60 | ) 61 | )); 62 | if ( is_wp_error( $captcha_result ) ) { 63 | $valid_captcha = false; 64 | } else { 65 | $captcha_response = json_decode( $captcha_result['body'], true ); 66 | if ( ! $captcha_response['success'] || ! $captcha_response['action'] == $action || $captcha_response['score'] < 0.5 ) { 67 | $valid_captcha = false; 68 | } 69 | } 70 | } 71 | } else { 72 | $valid_captcha = false; 73 | } 74 | } 75 | 76 | // get user email 77 | if ( isset($current_user) && $current_user->ID > 0 ) { 78 | $current_user_email = $current_user->data->user_email; 79 | } 80 | 81 | // get post permalink 82 | $post_permalink = get_permalink( $post_ID ); 83 | 84 | // challenge question 85 | $challenge_question_state = get_option( 'subscribe_reloaded_use_challenge_question', 'no' ); 86 | $challenge_question = get_option( 'subscribe_reloaded_challenge_question', 'What is 1 + 2?' ); 87 | $challenge_answer = get_option( 'subscribe_reloaded_challenge_answer', '3' ); 88 | 89 | // start output buffer 90 | ob_start(); 91 | 92 | // email address supplied 93 | if ( ! empty( $email ) ) { 94 | 95 | // check email validity 96 | $stcr_post_email = $wp_subscribe_reloaded->stcr->utils->check_valid_email( $email ); 97 | 98 | // check challenge question validity 99 | if ( $challenge_question_state == 'yes' ) { 100 | $challenge_user_answer = sanitize_text_field( $_POST['subscribe_reloaded_challenge'] ); 101 | if ( $challenge_answer != $challenge_user_answer ) { 102 | $valid_challenge = false; 103 | $valid_all = false; 104 | } 105 | } 106 | 107 | // email is invalid 108 | if ( $stcr_post_email === false ) { 109 | $valid_email = false; 110 | $valid_all = false; 111 | } 112 | 113 | // captcha is not valid 114 | if ( ! $valid_captcha ) { 115 | $valid_all = false; 116 | } 117 | 118 | // email is valid 119 | if ( $valid_all ) { 120 | 121 | // Use Akismet, if available, to check this user is legit 122 | if ( function_exists( 'akismet_http_post' ) ) { 123 | 124 | global $akismet_api_host, $akismet_api_port; 125 | 126 | $user_agent = isset( $_SERVER['HTTP_USER_AGENT'] ) ? sanitize_text_field( wp_unslash( $_SERVER['HTTP_USER_AGENT'] ) ) : ''; 127 | $akismet_query_string = "user_ip={$_SERVER['REMOTE_ADDR']}"; 128 | $akismet_query_string .= "&user_agent=" . esc_url( stripslashes( $user_agent ) ); 129 | $akismet_query_string .= "&blog=" . esc_url( get_option( 'home' ) ); 130 | $akismet_query_string .= "&blog_lang=" . get_locale(); 131 | $akismet_query_string .= "&blog_charset=" . get_option( 'blog_charset' ); 132 | $akismet_query_string .= "&permalink=".esc_url( $post_permalink ); 133 | $akismet_query_string .= "&comment_author_email=" . esc_url( sanitize_email( $email ) ); 134 | 135 | $akismet_response = akismet_http_post( $akismet_query_string, $akismet_api_host, '/1.1/comment-check', $akismet_api_port ); 136 | 137 | // If this is considered SPAM, we stop here 138 | if ( $akismet_response[1] == 'true' ) { 139 | ob_end_clean(); 140 | return ''; 141 | } 142 | 143 | } 144 | 145 | // sanitize email address 146 | $clean_email = $wp_subscribe_reloaded->stcr->utils->clean_email( $email ); 147 | 148 | // notify the administrator about the new subscription 149 | if ( get_option( 'subscribe_reloaded_enable_admin_messages' ) == 'yes' ) { 150 | 151 | $from_name = stripslashes( get_option( 'subscribe_reloaded_from_name', 'admin' ) ); 152 | $from_email = get_option( 'subscribe_reloaded_from_email', get_bloginfo( 'admin_email' ) ); 153 | 154 | $subject = esc_html__( 'New subscription to', 'subscribe-to-comments-reloaded' ) . " $target_post->post_title"; 155 | $message = esc_html__( 'New subscription to', 'subscribe-to-comments-reloaded' ) . " $target_post->post_title\n" . esc_html__( 'User:', 'subscribe-to-comments-reloaded' ) . " $clean_email"; 156 | 157 | $email_settings = array( 158 | 'subject' => $subject, 159 | 'message' => $message, 160 | 'toEmail' => get_bloginfo( 'admin_email' ) 161 | ); 162 | 163 | $has_blacklist_email = $this->utils->blacklisted_emails( $clean_email ); 164 | // Send the confirmation email only if the email 165 | // address is not in blacklist email list. 166 | if ( $has_blacklist_email ) { 167 | $wp_subscribe_reloaded->stcr->utils->send_email( $email_settings ); 168 | } 169 | 170 | } 171 | 172 | // double check, send confirmation email 173 | if ( get_option( 'subscribe_reloaded_enable_double_check' ) == 'yes' && ! $wp_subscribe_reloaded->stcr->is_user_subscribed( $post_ID, $clean_email, 'C' ) ) { 174 | $wp_subscribe_reloaded->stcr->add_subscription( $post_ID, $clean_email, 'YC' ); 175 | $wp_subscribe_reloaded->stcr->confirmation_email( $post_ID, $clean_email ); 176 | $message = html_entity_decode( stripslashes( get_option( 'subscribe_reloaded_subscription_confirmed_dci' ) ), ENT_QUOTES, 'UTF-8' ); 177 | 178 | // not double check, add subscription 179 | } else { 180 | $this->add_subscription( $post_ID, $clean_email, 'Y' ); 181 | $message = html_entity_decode( stripslashes( get_option( 'subscribe_reloaded_subscription_confirmed' ) ), ENT_QUOTES, 'UTF-8' ); 182 | } 183 | 184 | // new subscription message 185 | $message = str_replace( '[post_permalink]', $post_permalink, $message ); 186 | if ( function_exists( 'qtrans_useCurrentLanguageIfNotFoundUseDefaultLanguage' ) ) { 187 | $message = str_replace( '[post_title]', qtrans_useCurrentLanguageIfNotFoundUseDefaultLanguage( $target_post->post_title ), $message ); 188 | $message = qtrans_useCurrentLanguageIfNotFoundUseDefaultLanguage( $message ); 189 | } else { 190 | $message = str_replace( '[post_title]', $target_post->post_title, $message ); 191 | } 192 | 193 | echo wp_kses( wpautop( $message ), wp_kses_allowed_html( 'post' ) ); 194 | 195 | } 196 | 197 | // no email address supplied 198 | } else { 199 | 200 | // email value for input field 201 | if ( isset( $current_user_email ) ) { 202 | $email = $current_user_email; 203 | } else if ( isset( $_COOKIE['comment_author_email_' . COOKIEHASH] )) { 204 | $email = sanitize_email( wp_unslash( $_COOKIE[ 'comment_author_email_' . COOKIEHASH ] ) ); 205 | } else { 206 | $email = ''; 207 | } 208 | 209 | // output message for subscribing without commenting 210 | $message = str_replace( '[post_permalink]', $post_permalink, html_entity_decode( stripslashes( get_option( 'subscribe_reloaded_subscribe_without_commenting' ) ), ENT_QUOTES, 'UTF-8' ) ); 211 | if ( function_exists( 'qtrans_useCurrentLanguageIfNotFoundUseDefaultLanguage' ) ) { 212 | $message = str_replace( '[post_title]', qtrans_useCurrentLanguageIfNotFoundUseDefaultLanguage( $target_post->post_title ), $message ); 213 | $message = qtrans_useCurrentLanguageIfNotFoundUseDefaultLanguage( $message ); 214 | } else { 215 | $message = str_replace( '[post_title]', $target_post->post_title, $message ); 216 | } 217 | echo '

' . wp_kses( $message, wp_kses_allowed_html( 'post' ) ) . '

'; 218 | 219 | // output the form 220 | 221 | 222 | ?> 223 | 224 |
225 |
226 |
227 | 228 |

229 | 230 | 231 |

232 |

233 | 234 | 235 |

236 |

237 | 238 |

239 | 240 | 241 | 242 |

243 | 244 | 245 | 246 |

247 | 248 | 249 | 250 |
251 |
252 |
253 | 259 |
260 | 261 | 280 |
281 | post_title ), $message ); 291 | $message = qtrans_useCurrentLanguageIfNotFoundUseDefaultLanguage( $message ); 292 | } else { 293 | $message = str_replace( '[post_title]', esc_html( $target_post->post_title ), $message ); 294 | } 295 | echo '

' . wp_kses( $message, wp_kses_allowed_html( 'post' ) ) . '

'; 296 | 297 | ?> 298 | 299 |
300 |
301 | 302 | 303 |

304 | 305 | 306 |

307 |

308 | 309 | 310 |

311 |

312 | 313 |

314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 |

326 | 327 | 328 | 329 |

330 | 331 | 332 | 333 |

334 | 335 | 336 |
337 |
338 | 347 | -------------------------------------------------------------------------------- /src/templates/user.php: -------------------------------------------------------------------------------- 1 | stcr->delete_subscriptions( $post_list, $email ); 38 | echo '

' . esc_html__( 'Subscriptions deleted:', 'subscribe-to-comments-reloaded' ) . esc_html( $rows_affected ) . '

'; 39 | break; 40 | case 'suspend': 41 | $rows_affected = $wp_subscribe_reloaded->stcr->update_subscription_status( $post_list, $email, 'C' ); 42 | echo '

' . esc_html__( 'Subscriptions suspended:', 'subscribe-to-comments-reloaded' ) . esc_html( $rows_affected ) . '

'; 43 | break; 44 | case 'activate': 45 | $rows_affected = $wp_subscribe_reloaded->stcr->update_subscription_status( $post_list, $email, '-C' ); 46 | echo '

' . esc_html__( 'Subscriptions activated:', 'subscribe-to-comments-reloaded' ) . esc_html( $rows_affected ) . '

'; 47 | break; 48 | case 'force_y': 49 | $rows_affected = $wp_subscribe_reloaded->stcr->update_subscription_status( $post_list, $email, 'Y' ); 50 | echo '

' . esc_html__( 'Subscriptions updated:', 'subscribe-to-comments-reloaded' ) . esc_html( $rows_affected ) . '

'; 51 | break; 52 | case 'force_r': 53 | $rows_affected = $wp_subscribe_reloaded->stcr->update_subscription_status( $post_list, $email, 'R' ); 54 | echo '

' . esc_html__( 'Subscriptions updated:', 'subscribe-to-comments-reloaded' ) . esc_html( $rows_affected ) . '

'; 55 | break; 56 | default: 57 | break; 58 | } 59 | } 60 | $message = html_entity_decode( stripslashes( get_option( 'subscribe_reloaded_user_text' ) ), ENT_QUOTES, 'UTF-8' ); 61 | 62 | if ( function_exists( 'qtrans_useCurrentLanguageIfNotFoundUseDefaultLanguage' ) ) { 63 | $message = qtrans_useCurrentLanguageIfNotFoundUseDefaultLanguage( $message ); 64 | } 65 | 66 | echo "

" . wp_kses( $message, wp_kses_allowed_html( 'post' ) ) . "

"; 67 | 68 | ?> 69 | 70 | 71 |
72 |
73 | stcr->get_subscriptions( 'email', 'equals', $email, 'dt', 'DESC' ); 75 | // Let us translate those status 76 | $legend_translate = array( 77 | 'R' => esc_html__( 'Replies', 'subscribe-to-comments-reloaded'), 78 | 'RC' => esc_html__( 'Replies Unconfirmed', 'subscribe-to-comments-reloaded'), 79 | 'Y' => esc_html__( "All Comments", 'subscribe-to-comments-reloaded'), 80 | 'YC' => esc_html__( "Unconfirmed", 'subscribe-to-comments-reloaded'), 81 | 'C' => esc_html__( "Inactive", 'subscribe-to-comments-reloaded'), 82 | '-C' => esc_html__( "Active", 'subscribe-to-comments-reloaded') 83 | ); 84 | if ( is_array( $subscriptions ) && ! empty( $subscriptions ) ) { 85 | $total_subscriptions = count( $subscriptions ); 86 | $subscriptions_per_page = 200; 87 | $subscriptions_total_pages = ceil( $total_subscriptions / $subscriptions_per_page ); 88 | $subscriptions_pagenum = isset( $_REQUEST['subscription_paged'] ) ? absint( $_REQUEST['subscription_paged'] ) : 1; // phpcs:ignore WordPress.Security.NonceVerification.Recommended 89 | $subscriptions_offset = ( $subscriptions_pagenum - 1 ) * $subscriptions_per_page; 90 | $subscriptions = array_slice( $subscriptions, $subscriptions_offset, $subscriptions_per_page ); 91 | 92 | $disable_first = false; 93 | $disable_last = false; 94 | $disable_prev = false; 95 | $disable_next = false; 96 | 97 | if ( 1 == $subscriptions_pagenum ) { // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison 98 | $disable_first = true; 99 | $disable_prev = true; 100 | } 101 | 102 | if ( $subscriptions_total_pages == $subscriptions_pagenum ) { // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison 103 | $disable_last = true; 104 | $disable_next = true; 105 | } 106 | 107 | // For generating new url. 108 | $removable_query_args = array( 'post_permalink' ); 109 | $server_http_host = isset( $_SERVER['HTTP_HOST'] ) ? sanitize_text_field( wp_unslash( $_SERVER['HTTP_HOST'] ) ) : ''; 110 | $server_request_uri = isset( $_SERVER['REQUEST_URI'] ) ? sanitize_text_field( wp_unslash( $_SERVER['REQUEST_URI'] ) ) : ''; 111 | $current_url = set_url_scheme( 'http://' . $server_http_host . $server_request_uri ); 112 | $current_url = remove_query_arg( $removable_query_args, $current_url ); 113 | 114 | echo '

' . esc_html__( 'Email to manage', 'subscribe-to-comments-reloaded' ) . ': ' . esc_html( $email ) . '

'; 115 | 116 | echo " 117 | 118 | 119 | 120 | "; 121 | echo ""; 122 | 123 | foreach ( $subscriptions as $i => $a_subscription ) { 124 | $t_status = $a_subscription->status; 125 | $permalink = esc_url( get_permalink( $a_subscription->post_id ) ); 126 | $title = get_the_title( $a_subscription->post_id ); 127 | $date = strtotime( $a_subscription->dt ); 128 | $formatted_date = date( get_option( "subscribe_reloaded_date_format" ), $date ); 129 | $date_translated = $wp_subscribe_reloaded->stcr->utils->stcr_translate_month( $formatted_date ); 130 | 131 | echo ""; 132 | echo ""; 133 | echo ""; 134 | echo ""; 135 | echo ""; 136 | } 137 | echo ""; 138 | echo "
  ". esc_html__('Subscription Date','subscribe-to-comments-reloaded')."  ". esc_html__('Title','subscribe-to-comments-reloaded')."  ". esc_html__('Subscription Status','subscribe-to-comments-reloaded')."
" . esc_html( $title ) . " " . esc_html( $legend_translate[ $t_status ] ) . "
"; 139 | ?> 140 | 141 | 1 ) { ?> 142 | 213 | 214 | 215 | 217 |   218 | '; 219 | echo '    220 |

'; 221 | echo '

' . esc_html__( 'Action:', 'subscribe-to-comments-reloaded' ); 222 | 223 | $show_option_all = true; 224 | $show_option_replies = true; 225 | 226 | if ( get_option( 'subscribe_reloaded_enable_advanced_subscriptions', 'no' ) == 'no' ) { 227 | if ( get_option( 'subscribe_reloaded_checked_by_default_value', '0' ) == '0' ) { 228 | $show_option_replies = false; 229 | } else { 230 | $show_option_all = false; 231 | } 232 | } 233 | 234 | echo ''; 245 | 246 | echo '   247 |

'; 248 | 249 | if ( isset( $post_permalink ) ) 250 | { 251 | echo '

252 |   '. esc_html__('Return to Post','subscribe-to-comments-reloaded').' 253 |

'; 254 | } 255 | } else { 256 | echo '

' . esc_html__( 'No subscriptions match your search criteria.', 'subscribe-to-comments-reloaded' ) . '

'; 257 | } 258 | ?> 259 |
260 |
261 | 262 | 291 | 296 | -------------------------------------------------------------------------------- /src/templates/wrong-request.php: -------------------------------------------------------------------------------- 1 | ' . esc_html__( 'You have request to manage another email address and this is forbidden.', 'subscribe-to-comments-reloaded' ) . '

'; 10 | $output = ob_get_contents(); 11 | ob_end_clean(); 12 | 13 | return $output; 14 | ?> 15 | -------------------------------------------------------------------------------- /src/uninstall.php: -------------------------------------------------------------------------------- 1 | option_name ); 21 | } 22 | 23 | // delete settings and subscriptions 24 | } else if ( $safeUnistall === 'no' ) { 25 | 26 | // delete subscriptions 27 | $wpdb->query( "DROP TABLE IF EXISTS {$wpdb->prefix}subscribe_reloaded" ); // Compatibility with versions prior to 1.7 28 | $wpdb->query( "DROP TABLE IF EXISTS {$wpdb->prefix}subscribe_reloaded_subscribers" ); // Compatibility with versions prior to 1.7 29 | $wpdb->query( "DELETE FROM $wpdb->postmeta WHERE meta_key LIKE '\_stcr@\_%'" ); 30 | 31 | // delete settings 32 | foreach($stcr_options as $option) { 33 | delete_option( $option->option_name ); 34 | } 35 | 36 | } 37 | 38 | // remove scheduled autopurge events 39 | wp_clear_scheduled_hook( '_cron_subscribe_reloaded_purge' ); 40 | wp_clear_scheduled_hook( '_cron_subscribe_reloaded_system_report_file_purge' ); 41 | 42 | /** 43 | * Function to get all the settings info 44 | * 45 | * @since 190705 cleanup 46 | */ 47 | function stcr_get_settings($_wpdb) { 48 | 49 | // get the options 50 | $stcr_options = $_wpdb->get_results( 51 | "SELECT * FROM $_wpdb->options 52 | WHERE option_name 53 | LIKE 'subscribe_reloaded\_%' 54 | ORDER BY option_name", OBJECT 55 | ); 56 | 57 | // pass back the data 58 | return $stcr_options; 59 | 60 | } -------------------------------------------------------------------------------- /src/utils/functions.php: -------------------------------------------------------------------------------- 1 | stcr->utils->clean_email( $data['email'] ); 74 | 75 | // notify the administrator about the new subscription 76 | if ( $notify_admin ) { 77 | 78 | $from_name = stripslashes( get_option( 'subscribe_reloaded_from_name', 'admin' ) ); 79 | $from_email = get_option( 'subscribe_reloaded_from_email', get_bloginfo( 'admin_email' ) ); 80 | 81 | $subject = esc_html__( 'New subscription to', 'subscribe-to-comments-reloaded' ) . ' ' . get_the_title( $data['post_id'] ); 82 | $message = esc_html__( 'New subscription to', 'subscribe-to-comments-reloaded' ) . ' ' . get_the_title( $data['post_id'] ) . PHP_EOL . esc_html__( 'User:', 'subscribe-to-comments-reloaded' ) . " $clean_email"; 83 | 84 | $email_settings = array( 85 | 'subject' => $subject, 86 | 'message' => $message, 87 | 'toEmail' => get_bloginfo( 'admin_email' ) 88 | ); 89 | 90 | $wp_subscribe_reloaded->stcr->utils->send_email( $email_settings ); 91 | 92 | } 93 | 94 | // double check, send confirmation email 95 | if ( $notify_subscriber && ! $wp_subscribe_reloaded->stcr->is_user_subscribed( $data['post_id'], $clean_email, 'C' ) ) { 96 | 97 | $wp_subscribe_reloaded->stcr->add_subscription( $data['post_id'], $clean_email, $status ); 98 | $wp_subscribe_reloaded->stcr->confirmation_email( $data['post_id'], $clean_email ); 99 | 100 | // not double check, add subscription 101 | } else { 102 | $wp_subscribe_reloaded->stcr->add_subscription( $data['post_id'], $clean_email, $status ); 103 | } 104 | 105 | } 106 | 107 | } 108 | -------------------------------------------------------------------------------- /src/wpml-config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | --------------------------------------------------------------------------------