Widget Context - Version 1.3.0

Version Description

(April 23, 2020) =

  • Introduce the long-awaited "Exclude by URL" feature to prevent certain URLs from showing or hiding a widget when it's matched by any other visibility rule.
  • Introduce premium support to help maintain the plugin. Subscribe now to get the PRO version of the Widget Context for free when it's launched!
Download this release

Release Info

Developer kasparsd
Plugin Icon 128x128 Widget Context
Version 1.3.0
Comparing to
See all releases

Code changes from version 1.2.0 to 1.3.0

assets/css/admin.css CHANGED
@@ -7,7 +7,7 @@
7
 
8
  .widget-context .widget-context-header { float:left; width:100%; clear:both; }
9
  .widget-context .widget-context-header h3 { font-size:1.1em; margin:0 0.5em 0.5em 0; padding:0; float:left; }
10
- .widget-context .widget-context-header a { float:right; }
11
 
12
  .widget-context .context-group { float:left; width:100%; clear:both; margin-bottom:0.5em; }
13
  .widget-context .context-toggle { margin:0 0 0.3em 0; display:block; text-decoration:none; color:inherit; font-weight:bold; }
@@ -36,12 +36,7 @@
36
 
37
  /** Settings UI **/
38
 
39
- .widget-context-form th { width:auto; }
40
- .widget-context-form ul { border-top:1px solid #ddd; margin:0 0 1em 0; padding:0; float:left; width:100%; clear:both; display:block; }
41
- .widget-context-form li { float:left; width:100%; clear:both; margin:0; padding:0.5em 0; border-bottom:1px solid #ddd; }
42
- .widget-context-form li label { vertical-align:middle; float:left; width:34%; margin:0 -100em 0 0; }
43
- .widget-context-form li label input { vertical-align:middle; }
44
- .widget-context-form .context-desc { font-style:italic; color:#666; margin:0 0 0 40%; }
45
  .widget-context-settings-wrap { padding-right:300px; }
46
  .widget-context-form { float:left; width:100%; margin-right:-100em; }
47
  .widget-context-sidebar { float:right; width:280px; position:relative; right:-300px; border:1px solid #ddd; }
@@ -51,6 +46,8 @@
51
  .wc-sidebar-credits { padding-bottom:0.5em; margin-bottom:1em; border-bottom:1px solid #ddd; }
52
  .wc-sidebar-credits img { float:left; margin:0 1em 1em 0; }
53
 
 
 
54
  /** Sets correct widget height when child element height changes **/
55
  .widget-control-actions,
56
  .widget-content,
7
 
8
  .widget-context .widget-context-header { float:left; width:100%; clear:both; }
9
  .widget-context .widget-context-header h3 { font-size:1.1em; margin:0 0.5em 0.5em 0; padding:0; float:left; }
10
+ .widget-context .widget-context-header { color:#ccc; }
11
 
12
  .widget-context .context-group { float:left; width:100%; clear:both; margin-bottom:0.5em; }
13
  .widget-context .context-toggle { margin:0 0 0.3em 0; display:block; text-decoration:none; color:inherit; font-weight:bold; }
36
 
37
  /** Settings UI **/
38
 
39
+ .widget-context-form .enabled-contexts-item { margin:0 0 1em 0; }
 
 
 
 
 
40
  .widget-context-settings-wrap { padding-right:300px; }
41
  .widget-context-form { float:left; width:100%; margin-right:-100em; }
42
  .widget-context-sidebar { float:right; width:280px; position:relative; right:-300px; border:1px solid #ddd; }
46
  .wc-sidebar-credits { padding-bottom:0.5em; margin-bottom:1em; border-bottom:1px solid #ddd; }
47
  .wc-sidebar-credits img { float:left; margin:0 1em 1em 0; }
48
 
49
+ #widget-context-pro:target td { background-color:#fff3cd; border:1px solid #ffeeba; border-radius:4px; padding-left:1em; }
50
+
51
  /** Sets correct widget height when child element height changes **/
52
  .widget-control-actions,
53
  .widget-content,
composer.lock CHANGED
@@ -146,44 +146,46 @@
146
  },
147
  {
148
  "name": "guzzlehttp/guzzle",
149
- "version": "6.3.3",
150
  "source": {
151
  "type": "git",
152
  "url": "https://github.com/guzzle/guzzle.git",
153
- "reference": "407b0cb880ace85c9b63c5f9551db498cb2d50ba"
154
  },
155
  "dist": {
156
  "type": "zip",
157
- "url": "https://api.github.com/repos/guzzle/guzzle/zipball/407b0cb880ace85c9b63c5f9551db498cb2d50ba",
158
- "reference": "407b0cb880ace85c9b63c5f9551db498cb2d50ba",
159
  "shasum": ""
160
  },
161
  "require": {
 
162
  "guzzlehttp/promises": "^1.0",
163
- "guzzlehttp/psr7": "^1.4",
164
  "php": ">=5.5"
165
  },
166
  "require-dev": {
167
  "ext-curl": "*",
168
  "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.4 || ^7.0",
169
- "psr/log": "^1.0"
170
  },
171
  "suggest": {
 
172
  "psr/log": "Required for using the Log middleware"
173
  },
174
  "type": "library",
175
  "extra": {
176
  "branch-alias": {
177
- "dev-master": "6.3-dev"
178
  }
179
  },
180
  "autoload": {
181
- "files": [
182
- "src/functions_include.php"
183
- ],
184
  "psr-4": {
185
  "GuzzleHttp\\": "src/"
186
- }
 
 
 
187
  },
188
  "notification-url": "https://packagist.org/downloads/",
189
  "license": [
@@ -207,7 +209,7 @@
207
  "rest",
208
  "web service"
209
  ],
210
- "time": "2018-04-22T15:46:56+00:00"
211
  },
212
  {
213
  "name": "guzzlehttp/promises",
@@ -488,16 +490,16 @@
488
  },
489
  {
490
  "name": "pdepend/pdepend",
491
- "version": "2.5.2",
492
  "source": {
493
  "type": "git",
494
  "url": "https://github.com/pdepend/pdepend.git",
495
- "reference": "9daf26d0368d4a12bed1cacae1a9f3a6f0adf239"
496
  },
497
  "dist": {
498
  "type": "zip",
499
- "url": "https://api.github.com/repos/pdepend/pdepend/zipball/9daf26d0368d4a12bed1cacae1a9f3a6f0adf239",
500
- "reference": "9daf26d0368d4a12bed1cacae1a9f3a6f0adf239",
501
  "shasum": ""
502
  },
503
  "require": {
@@ -507,7 +509,9 @@
507
  "symfony/filesystem": "^2.3.0|^3|^4"
508
  },
509
  "require-dev": {
510
- "phpunit/phpunit": "^4.8|^5.7",
 
 
511
  "squizlabs/php_codesniffer": "^2.0.0"
512
  },
513
  "bin": [
@@ -524,20 +528,20 @@
524
  "BSD-3-Clause"
525
  ],
526
  "description": "Official version of pdepend to be handled with Composer",
527
- "time": "2017-12-13T13:21:38+00:00"
528
  },
529
  {
530
  "name": "php-coveralls/php-coveralls",
531
- "version": "v2.1.0",
532
  "source": {
533
  "type": "git",
534
  "url": "https://github.com/php-coveralls/php-coveralls.git",
535
- "reference": "3b00c229726f892bfdadeaf01ea430ffd04a939d"
536
  },
537
  "dist": {
538
  "type": "zip",
539
- "url": "https://api.github.com/repos/php-coveralls/php-coveralls/zipball/3b00c229726f892bfdadeaf01ea430ffd04a939d",
540
- "reference": "3b00c229726f892bfdadeaf01ea430ffd04a939d",
541
  "shasum": ""
542
  },
543
  "require": {
@@ -546,10 +550,10 @@
546
  "guzzlehttp/guzzle": "^6.0",
547
  "php": "^5.5 || ^7.0",
548
  "psr/log": "^1.0",
549
- "symfony/config": "^2.1 || ^3.0 || ^4.0",
550
- "symfony/console": "^2.1 || ^3.0 || ^4.0",
551
- "symfony/stopwatch": "^2.0 || ^3.0 || ^4.0",
552
- "symfony/yaml": "^2.0 || ^3.0 || ^4.0"
553
  },
554
  "require-dev": {
555
  "phpunit/phpunit": "^4.8.35 || ^5.4.3 || ^6.0"
@@ -563,7 +567,7 @@
563
  "type": "library",
564
  "extra": {
565
  "branch-alias": {
566
- "dev-master": "2.1-dev"
567
  }
568
  },
569
  "autoload": {
@@ -578,9 +582,9 @@
578
  "authors": [
579
  {
580
  "name": "Kitamura Satoshi",
581
- "role": "Original creator",
582
  "email": "with.no.parachute@gmail.com",
583
- "homepage": "https://www.facebook.com/satooshi.jp"
 
584
  },
585
  {
586
  "name": "Takashi Matsuo",
@@ -607,20 +611,20 @@
607
  "github",
608
  "test"
609
  ],
610
- "time": "2018-05-22T23:11:08+00:00"
611
  },
612
  {
613
  "name": "phpcompatibility/php-compatibility",
614
- "version": "9.2.0",
615
  "source": {
616
  "type": "git",
617
  "url": "https://github.com/PHPCompatibility/PHPCompatibility.git",
618
- "reference": "3db1bf1e28123fd574a4ae2e9a84072826d51b5e"
619
  },
620
  "dist": {
621
  "type": "zip",
622
- "url": "https://api.github.com/repos/PHPCompatibility/PHPCompatibility/zipball/3db1bf1e28123fd574a4ae2e9a84072826d51b5e",
623
- "reference": "3db1bf1e28123fd574a4ae2e9a84072826d51b5e",
624
  "shasum": ""
625
  },
626
  "require": {
@@ -643,19 +647,19 @@
643
  "LGPL-3.0-or-later"
644
  ],
645
  "authors": [
646
- {
647
- "name": "Contributors",
648
- "homepage": "https://github.com/PHPCompatibility/PHPCompatibility/graphs/contributors"
649
- },
650
  {
651
  "name": "Wim Godden",
652
- "role": "lead",
653
- "homepage": "https://github.com/wimg"
654
  },
655
  {
656
  "name": "Juliette Reinders Folmer",
657
- "role": "lead",
658
- "homepage": "https://github.com/jrfnl"
 
 
 
 
659
  }
660
  ],
661
  "description": "A set of sniffs for PHP_CodeSniffer that checks for PHP cross-version compatibility.",
@@ -665,7 +669,7 @@
665
  "phpcs",
666
  "standards"
667
  ],
668
- "time": "2019-06-27T19:58:56+00:00"
669
  },
670
  {
671
  "name": "phpdocumentor/reflection-common",
@@ -883,33 +887,33 @@
883
  },
884
  {
885
  "name": "phpspec/prophecy",
886
- "version": "1.8.1",
887
  "source": {
888
  "type": "git",
889
  "url": "https://github.com/phpspec/prophecy.git",
890
- "reference": "1927e75f4ed19131ec9bcc3b002e07fb1173ee76"
891
  },
892
  "dist": {
893
  "type": "zip",
894
- "url": "https://api.github.com/repos/phpspec/prophecy/zipball/1927e75f4ed19131ec9bcc3b002e07fb1173ee76",
895
- "reference": "1927e75f4ed19131ec9bcc3b002e07fb1173ee76",
896
  "shasum": ""
897
  },
898
  "require": {
899
  "doctrine/instantiator": "^1.0.2",
900
  "php": "^5.3|^7.0",
901
- "phpdocumentor/reflection-docblock": "^2.0|^3.0.2|^4.0",
902
- "sebastian/comparator": "^1.1|^2.0|^3.0",
903
  "sebastian/recursion-context": "^1.0|^2.0|^3.0"
904
  },
905
  "require-dev": {
906
- "phpspec/phpspec": "^2.5|^3.2",
907
  "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5 || ^7.1"
908
  },
909
  "type": "library",
910
  "extra": {
911
  "branch-alias": {
912
- "dev-master": "1.8.x-dev"
913
  }
914
  },
915
  "autoload": {
@@ -942,7 +946,7 @@
942
  "spy",
943
  "stub"
944
  ],
945
- "time": "2019-06-13T12:50:23+00:00"
946
  },
947
  {
948
  "name": "phpunit/php-code-coverage",
@@ -1436,16 +1440,16 @@
1436
  },
1437
  {
1438
  "name": "psr/log",
1439
- "version": "1.1.0",
1440
  "source": {
1441
  "type": "git",
1442
  "url": "https://github.com/php-fig/log.git",
1443
- "reference": "6c001f1daafa3a3ac1d8ff69ee4db8e799a654dd"
1444
  },
1445
  "dist": {
1446
  "type": "zip",
1447
- "url": "https://api.github.com/repos/php-fig/log/zipball/6c001f1daafa3a3ac1d8ff69ee4db8e799a654dd",
1448
- "reference": "6c001f1daafa3a3ac1d8ff69ee4db8e799a654dd",
1449
  "shasum": ""
1450
  },
1451
  "require": {
@@ -1454,7 +1458,7 @@
1454
  "type": "library",
1455
  "extra": {
1456
  "branch-alias": {
1457
- "dev-master": "1.0.x-dev"
1458
  }
1459
  },
1460
  "autoload": {
@@ -1479,7 +1483,7 @@
1479
  "psr",
1480
  "psr-3"
1481
  ],
1482
- "time": "2018-11-20T15:27:04+00:00"
1483
  },
1484
  {
1485
  "name": "ralouphie/getallheaders",
@@ -2036,16 +2040,16 @@
2036
  },
2037
  {
2038
  "name": "squizlabs/php_codesniffer",
2039
- "version": "3.4.2",
2040
  "source": {
2041
  "type": "git",
2042
  "url": "https://github.com/squizlabs/PHP_CodeSniffer.git",
2043
- "reference": "b8a7362af1cc1aadb5bd36c3defc4dda2cf5f0a8"
2044
  },
2045
  "dist": {
2046
  "type": "zip",
2047
- "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/b8a7362af1cc1aadb5bd36c3defc4dda2cf5f0a8",
2048
- "reference": "b8a7362af1cc1aadb5bd36c3defc4dda2cf5f0a8",
2049
  "shasum": ""
2050
  },
2051
  "require": {
@@ -2083,20 +2087,20 @@
2083
  "phpcs",
2084
  "standards"
2085
  ],
2086
- "time": "2019-04-10T23:49:02+00:00"
2087
  },
2088
  {
2089
  "name": "symfony/config",
2090
- "version": "v3.4.30",
2091
  "source": {
2092
  "type": "git",
2093
  "url": "https://github.com/symfony/config.git",
2094
- "reference": "623fd6be3e5d4112d667003488c8c3ec12b66f62"
2095
  },
2096
  "dist": {
2097
  "type": "zip",
2098
- "url": "https://api.github.com/repos/symfony/config/zipball/623fd6be3e5d4112d667003488c8c3ec12b66f62",
2099
- "reference": "623fd6be3e5d4112d667003488c8c3ec12b66f62",
2100
  "shasum": ""
2101
  },
2102
  "require": {
@@ -2147,20 +2151,20 @@
2147
  ],
2148
  "description": "Symfony Config Component",
2149
  "homepage": "https://symfony.com",
2150
- "time": "2019-07-17T15:23:18+00:00"
2151
  },
2152
  {
2153
  "name": "symfony/console",
2154
- "version": "v3.4.30",
2155
  "source": {
2156
  "type": "git",
2157
  "url": "https://github.com/symfony/console.git",
2158
- "reference": "12940f20a816c978860fa4925b3f1bbb27e9ac46"
2159
  },
2160
  "dist": {
2161
  "type": "zip",
2162
- "url": "https://api.github.com/repos/symfony/console/zipball/12940f20a816c978860fa4925b3f1bbb27e9ac46",
2163
- "reference": "12940f20a816c978860fa4925b3f1bbb27e9ac46",
2164
  "shasum": ""
2165
  },
2166
  "require": {
@@ -2219,20 +2223,20 @@
2219
  ],
2220
  "description": "Symfony Console Component",
2221
  "homepage": "https://symfony.com",
2222
- "time": "2019-07-24T14:46:41+00:00"
2223
  },
2224
  {
2225
  "name": "symfony/debug",
2226
- "version": "v3.4.30",
2227
  "source": {
2228
  "type": "git",
2229
  "url": "https://github.com/symfony/debug.git",
2230
- "reference": "bc977cb2681d75988ab2d53d14c4245c6c04f82f"
2231
  },
2232
  "dist": {
2233
  "type": "zip",
2234
- "url": "https://api.github.com/repos/symfony/debug/zipball/bc977cb2681d75988ab2d53d14c4245c6c04f82f",
2235
- "reference": "bc977cb2681d75988ab2d53d14c4245c6c04f82f",
2236
  "shasum": ""
2237
  },
2238
  "require": {
@@ -2275,20 +2279,20 @@
2275
  ],
2276
  "description": "Symfony Debug Component",
2277
  "homepage": "https://symfony.com",
2278
- "time": "2019-07-23T08:39:19+00:00"
2279
  },
2280
  {
2281
  "name": "symfony/dependency-injection",
2282
- "version": "v3.4.30",
2283
  "source": {
2284
  "type": "git",
2285
  "url": "https://github.com/symfony/dependency-injection.git",
2286
- "reference": "ade939fe83d5ec5fcaa98628dc42d83232c8eb41"
2287
  },
2288
  "dist": {
2289
  "type": "zip",
2290
- "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/ade939fe83d5ec5fcaa98628dc42d83232c8eb41",
2291
- "reference": "ade939fe83d5ec5fcaa98628dc42d83232c8eb41",
2292
  "shasum": ""
2293
  },
2294
  "require": {
@@ -2346,20 +2350,20 @@
2346
  ],
2347
  "description": "Symfony DependencyInjection Component",
2348
  "homepage": "https://symfony.com",
2349
- "time": "2019-07-19T11:52:08+00:00"
2350
  },
2351
  {
2352
  "name": "symfony/filesystem",
2353
- "version": "v3.4.30",
2354
  "source": {
2355
  "type": "git",
2356
  "url": "https://github.com/symfony/filesystem.git",
2357
- "reference": "70adda061ef83bb7def63a17953dc41f203308a7"
2358
  },
2359
  "dist": {
2360
  "type": "zip",
2361
- "url": "https://api.github.com/repos/symfony/filesystem/zipball/70adda061ef83bb7def63a17953dc41f203308a7",
2362
- "reference": "70adda061ef83bb7def63a17953dc41f203308a7",
2363
  "shasum": ""
2364
  },
2365
  "require": {
@@ -2396,20 +2400,20 @@
2396
  ],
2397
  "description": "Symfony Filesystem Component",
2398
  "homepage": "https://symfony.com",
2399
- "time": "2019-06-23T09:29:17+00:00"
2400
  },
2401
  {
2402
  "name": "symfony/polyfill-ctype",
2403
- "version": "v1.12.0",
2404
  "source": {
2405
  "type": "git",
2406
  "url": "https://github.com/symfony/polyfill-ctype.git",
2407
- "reference": "550ebaac289296ce228a706d0867afc34687e3f4"
2408
  },
2409
  "dist": {
2410
  "type": "zip",
2411
- "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/550ebaac289296ce228a706d0867afc34687e3f4",
2412
- "reference": "550ebaac289296ce228a706d0867afc34687e3f4",
2413
  "shasum": ""
2414
  },
2415
  "require": {
@@ -2421,7 +2425,7 @@
2421
  "type": "library",
2422
  "extra": {
2423
  "branch-alias": {
2424
- "dev-master": "1.12-dev"
2425
  }
2426
  },
2427
  "autoload": {
@@ -2454,20 +2458,20 @@
2454
  "polyfill",
2455
  "portable"
2456
  ],
2457
- "time": "2019-08-06T08:03:45+00:00"
2458
  },
2459
  {
2460
  "name": "symfony/polyfill-mbstring",
2461
- "version": "v1.12.0",
2462
  "source": {
2463
  "type": "git",
2464
  "url": "https://github.com/symfony/polyfill-mbstring.git",
2465
- "reference": "b42a2f66e8f1b15ccf25652c3424265923eb4f17"
2466
  },
2467
  "dist": {
2468
  "type": "zip",
2469
- "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/b42a2f66e8f1b15ccf25652c3424265923eb4f17",
2470
- "reference": "b42a2f66e8f1b15ccf25652c3424265923eb4f17",
2471
  "shasum": ""
2472
  },
2473
  "require": {
@@ -2479,7 +2483,7 @@
2479
  "type": "library",
2480
  "extra": {
2481
  "branch-alias": {
2482
- "dev-master": "1.12-dev"
2483
  }
2484
  },
2485
  "autoload": {
@@ -2513,20 +2517,20 @@
2513
  "portable",
2514
  "shim"
2515
  ],
2516
- "time": "2019-08-06T08:03:45+00:00"
2517
  },
2518
  {
2519
  "name": "symfony/stopwatch",
2520
- "version": "v3.4.30",
2521
  "source": {
2522
  "type": "git",
2523
  "url": "https://github.com/symfony/stopwatch.git",
2524
- "reference": "2a651c2645c10bbedd21170771f122d935e0dd58"
2525
  },
2526
  "dist": {
2527
  "type": "zip",
2528
- "url": "https://api.github.com/repos/symfony/stopwatch/zipball/2a651c2645c10bbedd21170771f122d935e0dd58",
2529
- "reference": "2a651c2645c10bbedd21170771f122d935e0dd58",
2530
  "shasum": ""
2531
  },
2532
  "require": {
@@ -2562,20 +2566,20 @@
2562
  ],
2563
  "description": "Symfony Stopwatch Component",
2564
  "homepage": "https://symfony.com",
2565
- "time": "2019-01-16T09:39:14+00:00"
2566
  },
2567
  {
2568
  "name": "symfony/yaml",
2569
- "version": "v3.4.30",
2570
  "source": {
2571
  "type": "git",
2572
  "url": "https://github.com/symfony/yaml.git",
2573
- "reference": "051d045c684148060ebfc9affb7e3f5e0899d40b"
2574
  },
2575
  "dist": {
2576
  "type": "zip",
2577
- "url": "https://api.github.com/repos/symfony/yaml/zipball/051d045c684148060ebfc9affb7e3f5e0899d40b",
2578
- "reference": "051d045c684148060ebfc9affb7e3f5e0899d40b",
2579
  "shasum": ""
2580
  },
2581
  "require": {
@@ -2621,36 +2625,33 @@
2621
  ],
2622
  "description": "Symfony Yaml Component",
2623
  "homepage": "https://symfony.com",
2624
- "time": "2019-07-24T13:01:31+00:00"
2625
  },
2626
  {
2627
  "name": "webmozart/assert",
2628
- "version": "1.4.0",
2629
  "source": {
2630
  "type": "git",
2631
  "url": "https://github.com/webmozart/assert.git",
2632
- "reference": "83e253c8e0be5b0257b881e1827274667c5c17a9"
2633
  },
2634
  "dist": {
2635
  "type": "zip",
2636
- "url": "https://api.github.com/repos/webmozart/assert/zipball/83e253c8e0be5b0257b881e1827274667c5c17a9",
2637
- "reference": "83e253c8e0be5b0257b881e1827274667c5c17a9",
2638
  "shasum": ""
2639
  },
2640
  "require": {
2641
  "php": "^5.3.3 || ^7.0",
2642
  "symfony/polyfill-ctype": "^1.8"
2643
  },
 
 
 
2644
  "require-dev": {
2645
- "phpunit/phpunit": "^4.6",
2646
- "sebastian/version": "^1.0.1"
2647
  },
2648
  "type": "library",
2649
- "extra": {
2650
- "branch-alias": {
2651
- "dev-master": "1.3-dev"
2652
- }
2653
- },
2654
  "autoload": {
2655
  "psr-4": {
2656
  "Webmozart\\Assert\\": "src/"
@@ -2672,20 +2673,20 @@
2672
  "check",
2673
  "validate"
2674
  ],
2675
- "time": "2018-12-25T11:19:39+00:00"
2676
  },
2677
  {
2678
  "name": "wp-coding-standards/wpcs",
2679
- "version": "2.1.1",
2680
  "source": {
2681
  "type": "git",
2682
  "url": "https://github.com/WordPress/WordPress-Coding-Standards.git",
2683
- "reference": "bd9c33152115e6741e3510ff7189605b35167908"
2684
  },
2685
  "dist": {
2686
  "type": "zip",
2687
- "url": "https://api.github.com/repos/WordPress/WordPress-Coding-Standards/zipball/bd9c33152115e6741e3510ff7189605b35167908",
2688
- "reference": "bd9c33152115e6741e3510ff7189605b35167908",
2689
  "shasum": ""
2690
  },
2691
  "require": {
@@ -2708,7 +2709,7 @@
2708
  "authors": [
2709
  {
2710
  "name": "Contributors",
2711
- "homepage": "https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards/graphs/contributors"
2712
  }
2713
  ],
2714
  "description": "PHP_CodeSniffer rules (sniffs) to enforce WordPress coding conventions",
@@ -2717,7 +2718,7 @@
2717
  "standards",
2718
  "wordpress"
2719
  ],
2720
- "time": "2019-05-21T02:50:00+00:00"
2721
  },
2722
  {
2723
  "name": "wpsh/local",
146
  },
147
  {
148
  "name": "guzzlehttp/guzzle",
149
+ "version": "6.5.0",
150
  "source": {
151
  "type": "git",
152
  "url": "https://github.com/guzzle/guzzle.git",
153
+ "reference": "dbc2bc3a293ed6b1ae08a3651e2bfd213d19b6a5"
154
  },
155
  "dist": {
156
  "type": "zip",
157
+ "url": "https://api.github.com/repos/guzzle/guzzle/zipball/dbc2bc3a293ed6b1ae08a3651e2bfd213d19b6a5",
158
+ "reference": "dbc2bc3a293ed6b1ae08a3651e2bfd213d19b6a5",
159
  "shasum": ""
160
  },
161
  "require": {
162
+ "ext-json": "*",
163
  "guzzlehttp/promises": "^1.0",
164
+ "guzzlehttp/psr7": "^1.6.1",
165
  "php": ">=5.5"
166
  },
167
  "require-dev": {
168
  "ext-curl": "*",
169
  "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.4 || ^7.0",
170
+ "psr/log": "^1.1"
171
  },
172
  "suggest": {
173
+ "ext-intl": "Required for Internationalized Domain Name (IDN) support",
174
  "psr/log": "Required for using the Log middleware"
175
  },
176
  "type": "library",
177
  "extra": {
178
  "branch-alias": {
179
+ "dev-master": "6.5-dev"
180
  }
181
  },
182
  "autoload": {
 
 
 
183
  "psr-4": {
184
  "GuzzleHttp\\": "src/"
185
+ },
186
+ "files": [
187
+ "src/functions_include.php"
188
+ ]
189
  },
190
  "notification-url": "https://packagist.org/downloads/",
191
  "license": [
209
  "rest",
210
  "web service"
211
  ],
212
+ "time": "2019-12-07T18:20:45+00:00"
213
  },
214
  {
215
  "name": "guzzlehttp/promises",
490
  },
491
  {
492
  "name": "pdepend/pdepend",
493
+ "version": "2.6.0",
494
  "source": {
495
  "type": "git",
496
  "url": "https://github.com/pdepend/pdepend.git",
497
+ "reference": "713e14e401d174882a5980446db1ba427922310b"
498
  },
499
  "dist": {
500
  "type": "zip",
501
+ "url": "https://api.github.com/repos/pdepend/pdepend/zipball/713e14e401d174882a5980446db1ba427922310b",
502
+ "reference": "713e14e401d174882a5980446db1ba427922310b",
503
  "shasum": ""
504
  },
505
  "require": {
509
  "symfony/filesystem": "^2.3.0|^3|^4"
510
  },
511
  "require-dev": {
512
+ "easy-doc/easy-doc": "0.0.0 || ^1.2.3",
513
+ "gregwar/rst": "^1.0",
514
+ "phpunit/phpunit": "^4.8.35|^5.7",
515
  "squizlabs/php_codesniffer": "^2.0.0"
516
  },
517
  "bin": [
528
  "BSD-3-Clause"
529
  ],
530
  "description": "Official version of pdepend to be handled with Composer",
531
+ "time": "2019-12-14T09:25:03+00:00"
532
  },
533
  {
534
  "name": "php-coveralls/php-coveralls",
535
+ "version": "v2.2.0",
536
  "source": {
537
  "type": "git",
538
  "url": "https://github.com/php-coveralls/php-coveralls.git",
539
+ "reference": "3e6420fa666ef7bae5e750ddeac903153e193bae"
540
  },
541
  "dist": {
542
  "type": "zip",
543
+ "url": "https://api.github.com/repos/php-coveralls/php-coveralls/zipball/3e6420fa666ef7bae5e750ddeac903153e193bae",
544
+ "reference": "3e6420fa666ef7bae5e750ddeac903153e193bae",
545
  "shasum": ""
546
  },
547
  "require": {
550
  "guzzlehttp/guzzle": "^6.0",
551
  "php": "^5.5 || ^7.0",
552
  "psr/log": "^1.0",
553
+ "symfony/config": "^2.1 || ^3.0 || ^4.0 || ^5.0",
554
+ "symfony/console": "^2.1 || ^3.0 || ^4.0 || ^5.0",
555
+ "symfony/stopwatch": "^2.0 || ^3.0 || ^4.0 || ^5.0",
556
+ "symfony/yaml": "^2.0.5 || ^3.0 || ^4.0 || ^5.0"
557
  },
558
  "require-dev": {
559
  "phpunit/phpunit": "^4.8.35 || ^5.4.3 || ^6.0"
567
  "type": "library",
568
  "extra": {
569
  "branch-alias": {
570
+ "dev-master": "2.2-dev"
571
  }
572
  },
573
  "autoload": {
582
  "authors": [
583
  {
584
  "name": "Kitamura Satoshi",
 
585
  "email": "with.no.parachute@gmail.com",
586
+ "homepage": "https://www.facebook.com/satooshi.jp",
587
+ "role": "Original creator"
588
  },
589
  {
590
  "name": "Takashi Matsuo",
611
  "github",
612
  "test"
613
  ],
614
+ "time": "2019-11-20T16:29:20+00:00"
615
  },
616
  {
617
  "name": "phpcompatibility/php-compatibility",
618
+ "version": "9.3.4",
619
  "source": {
620
  "type": "git",
621
  "url": "https://github.com/PHPCompatibility/PHPCompatibility.git",
622
+ "reference": "1f37659196e4f3113ea506a7efba201c52303bf1"
623
  },
624
  "dist": {
625
  "type": "zip",
626
+ "url": "https://api.github.com/repos/PHPCompatibility/PHPCompatibility/zipball/1f37659196e4f3113ea506a7efba201c52303bf1",
627
+ "reference": "1f37659196e4f3113ea506a7efba201c52303bf1",
628
  "shasum": ""
629
  },
630
  "require": {
647
  "LGPL-3.0-or-later"
648
  ],
649
  "authors": [
 
 
 
 
650
  {
651
  "name": "Wim Godden",
652
+ "homepage": "https://github.com/wimg",
653
+ "role": "lead"
654
  },
655
  {
656
  "name": "Juliette Reinders Folmer",
657
+ "homepage": "https://github.com/jrfnl",
658
+ "role": "lead"
659
+ },
660
+ {
661
+ "name": "Contributors",
662
+ "homepage": "https://github.com/PHPCompatibility/PHPCompatibility/graphs/contributors"
663
  }
664
  ],
665
  "description": "A set of sniffs for PHP_CodeSniffer that checks for PHP cross-version compatibility.",
669
  "phpcs",
670
  "standards"
671
  ],
672
+ "time": "2019-11-15T04:12:02+00:00"
673
  },
674
  {
675
  "name": "phpdocumentor/reflection-common",
887
  },
888
  {
889
  "name": "phpspec/prophecy",
890
+ "version": "1.10.0",
891
  "source": {
892
  "type": "git",
893
  "url": "https://github.com/phpspec/prophecy.git",
894
+ "reference": "d638ebbb58daba25a6a0dc7969e1358a0e3c6682"
895
  },
896
  "dist": {
897
  "type": "zip",
898
+ "url": "https://api.github.com/repos/phpspec/prophecy/zipball/d638ebbb58daba25a6a0dc7969e1358a0e3c6682",
899
+ "reference": "d638ebbb58daba25a6a0dc7969e1358a0e3c6682",
900
  "shasum": ""
901
  },
902
  "require": {
903
  "doctrine/instantiator": "^1.0.2",
904
  "php": "^5.3|^7.0",
905
+ "phpdocumentor/reflection-docblock": "^2.0|^3.0.2|^4.0|^5.0",
906
+ "sebastian/comparator": "^1.2.3|^2.0|^3.0",
907
  "sebastian/recursion-context": "^1.0|^2.0|^3.0"
908
  },
909
  "require-dev": {
910
+ "phpspec/phpspec": "^2.5 || ^3.2",
911
  "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5 || ^7.1"
912
  },
913
  "type": "library",
914
  "extra": {
915
  "branch-alias": {
916
+ "dev-master": "1.10.x-dev"
917
  }
918
  },
919
  "autoload": {
946
  "spy",
947
  "stub"
948
  ],
949
+ "time": "2019-12-17T16:54:23+00:00"
950
  },
951
  {
952
  "name": "phpunit/php-code-coverage",
1440
  },
1441
  {
1442
  "name": "psr/log",
1443
+ "version": "1.1.2",
1444
  "source": {
1445
  "type": "git",
1446
  "url": "https://github.com/php-fig/log.git",
1447
+ "reference": "446d54b4cb6bf489fc9d75f55843658e6f25d801"
1448
  },
1449
  "dist": {
1450
  "type": "zip",
1451
+ "url": "https://api.github.com/repos/php-fig/log/zipball/446d54b4cb6bf489fc9d75f55843658e6f25d801",
1452
+ "reference": "446d54b4cb6bf489fc9d75f55843658e6f25d801",
1453
  "shasum": ""
1454
  },
1455
  "require": {
1458
  "type": "library",
1459
  "extra": {
1460
  "branch-alias": {
1461
+ "dev-master": "1.1.x-dev"
1462
  }
1463
  },
1464
  "autoload": {
1483
  "psr",
1484
  "psr-3"
1485
  ],
1486
+ "time": "2019-11-01T11:05:21+00:00"
1487
  },
1488
  {
1489
  "name": "ralouphie/getallheaders",
2040
  },
2041
  {
2042
  "name": "squizlabs/php_codesniffer",
2043
+ "version": "3.5.3",
2044
  "source": {
2045
  "type": "git",
2046
  "url": "https://github.com/squizlabs/PHP_CodeSniffer.git",
2047
+ "reference": "557a1fc7ac702c66b0bbfe16ab3d55839ef724cb"
2048
  },
2049
  "dist": {
2050
  "type": "zip",
2051
+ "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/557a1fc7ac702c66b0bbfe16ab3d55839ef724cb",
2052
+ "reference": "557a1fc7ac702c66b0bbfe16ab3d55839ef724cb",
2053
  "shasum": ""
2054
  },
2055
  "require": {
2087
  "phpcs",
2088
  "standards"
2089
  ],
2090
+ "time": "2019-12-04T04:46:47+00:00"
2091
  },
2092
  {
2093
  "name": "symfony/config",
2094
+ "version": "v3.4.36",
2095
  "source": {
2096
  "type": "git",
2097
  "url": "https://github.com/symfony/config.git",
2098
+ "reference": "a599a867d0e4a07c342b5f1e656b3915a540ddbe"
2099
  },
2100
  "dist": {
2101
  "type": "zip",
2102
+ "url": "https://api.github.com/repos/symfony/config/zipball/a599a867d0e4a07c342b5f1e656b3915a540ddbe",
2103
+ "reference": "a599a867d0e4a07c342b5f1e656b3915a540ddbe",
2104
  "shasum": ""
2105
  },
2106
  "require": {
2151
  ],
2152
  "description": "Symfony Config Component",
2153
  "homepage": "https://symfony.com",
2154
+ "time": "2019-12-01T10:45:41+00:00"
2155
  },
2156
  {
2157
  "name": "symfony/console",
2158
+ "version": "v3.4.36",
2159
  "source": {
2160
  "type": "git",
2161
  "url": "https://github.com/symfony/console.git",
2162
+ "reference": "1ee23b3b659b06c622f2bd2492a229e416eb4586"
2163
  },
2164
  "dist": {
2165
  "type": "zip",
2166
+ "url": "https://api.github.com/repos/symfony/console/zipball/1ee23b3b659b06c622f2bd2492a229e416eb4586",
2167
+ "reference": "1ee23b3b659b06c622f2bd2492a229e416eb4586",
2168
  "shasum": ""
2169
  },
2170
  "require": {
2223
  ],
2224
  "description": "Symfony Console Component",
2225
  "homepage": "https://symfony.com",
2226
+ "time": "2019-12-01T10:04:45+00:00"
2227
  },
2228
  {
2229
  "name": "symfony/debug",
2230
+ "version": "v3.4.36",
2231
  "source": {
2232
  "type": "git",
2233
  "url": "https://github.com/symfony/debug.git",
2234
+ "reference": "f72e33fdb1170b326e72c3157f0cd456351dd086"
2235
  },
2236
  "dist": {
2237
  "type": "zip",
2238
+ "url": "https://api.github.com/repos/symfony/debug/zipball/f72e33fdb1170b326e72c3157f0cd456351dd086",
2239
+ "reference": "f72e33fdb1170b326e72c3157f0cd456351dd086",
2240
  "shasum": ""
2241
  },
2242
  "require": {
2279
  ],
2280
  "description": "Symfony Debug Component",
2281
  "homepage": "https://symfony.com",
2282
+ "time": "2019-10-24T15:33:53+00:00"
2283
  },
2284
  {
2285
  "name": "symfony/dependency-injection",
2286
+ "version": "v3.4.36",
2287
  "source": {
2288
  "type": "git",
2289
  "url": "https://github.com/symfony/dependency-injection.git",
2290
+ "reference": "0d201916bfb3af939fec3c0c8815ea16c60ac1a2"
2291
  },
2292
  "dist": {
2293
  "type": "zip",
2294
+ "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/0d201916bfb3af939fec3c0c8815ea16c60ac1a2",
2295
+ "reference": "0d201916bfb3af939fec3c0c8815ea16c60ac1a2",
2296
  "shasum": ""
2297
  },
2298
  "require": {
2350
  ],
2351
  "description": "Symfony DependencyInjection Component",
2352
  "homepage": "https://symfony.com",
2353
+ "time": "2019-12-01T08:33:36+00:00"
2354
  },
2355
  {
2356
  "name": "symfony/filesystem",
2357
+ "version": "v3.4.36",
2358
  "source": {
2359
  "type": "git",
2360
  "url": "https://github.com/symfony/filesystem.git",
2361
+ "reference": "00cdad0936d06fab136944bc2342b762b1c3a4a2"
2362
  },
2363
  "dist": {
2364
  "type": "zip",
2365
+ "url": "https://api.github.com/repos/symfony/filesystem/zipball/00cdad0936d06fab136944bc2342b762b1c3a4a2",
2366
+ "reference": "00cdad0936d06fab136944bc2342b762b1c3a4a2",
2367
  "shasum": ""
2368
  },
2369
  "require": {
2400
  ],
2401
  "description": "Symfony Filesystem Component",
2402
  "homepage": "https://symfony.com",
2403
+ "time": "2019-11-25T16:36:22+00:00"
2404
  },
2405
  {
2406
  "name": "symfony/polyfill-ctype",
2407
+ "version": "v1.13.1",
2408
  "source": {
2409
  "type": "git",
2410
  "url": "https://github.com/symfony/polyfill-ctype.git",
2411
+ "reference": "f8f0b461be3385e56d6de3dbb5a0df24c0c275e3"
2412
  },
2413
  "dist": {
2414
  "type": "zip",
2415
+ "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/f8f0b461be3385e56d6de3dbb5a0df24c0c275e3",
2416
+ "reference": "f8f0b461be3385e56d6de3dbb5a0df24c0c275e3",
2417
  "shasum": ""
2418
  },
2419
  "require": {
2425
  "type": "library",
2426
  "extra": {
2427
  "branch-alias": {
2428
+ "dev-master": "1.13-dev"
2429
  }
2430
  },
2431
  "autoload": {
2458
  "polyfill",
2459
  "portable"
2460
  ],
2461
+ "time": "2019-11-27T13:56:44+00:00"
2462
  },
2463
  {
2464
  "name": "symfony/polyfill-mbstring",
2465
+ "version": "v1.13.1",
2466
  "source": {
2467
  "type": "git",
2468
  "url": "https://github.com/symfony/polyfill-mbstring.git",
2469
+ "reference": "7b4aab9743c30be783b73de055d24a39cf4b954f"
2470
  },
2471
  "dist": {
2472
  "type": "zip",
2473
+ "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/7b4aab9743c30be783b73de055d24a39cf4b954f",
2474
+ "reference": "7b4aab9743c30be783b73de055d24a39cf4b954f",
2475
  "shasum": ""
2476
  },
2477
  "require": {
2483
  "type": "library",
2484
  "extra": {
2485
  "branch-alias": {
2486
+ "dev-master": "1.13-dev"
2487
  }
2488
  },
2489
  "autoload": {
2517
  "portable",
2518
  "shim"
2519
  ],
2520
+ "time": "2019-11-27T14:18:11+00:00"
2521
  },
2522
  {
2523
  "name": "symfony/stopwatch",
2524
+ "version": "v3.4.36",
2525
  "source": {
2526
  "type": "git",
2527
  "url": "https://github.com/symfony/stopwatch.git",
2528
+ "reference": "efe0af281ad336bc3b10375c88b117499f1d8494"
2529
  },
2530
  "dist": {
2531
  "type": "zip",
2532
+ "url": "https://api.github.com/repos/symfony/stopwatch/zipball/efe0af281ad336bc3b10375c88b117499f1d8494",
2533
+ "reference": "efe0af281ad336bc3b10375c88b117499f1d8494",
2534
  "shasum": ""
2535
  },
2536
  "require": {
2566
  ],
2567
  "description": "Symfony Stopwatch Component",
2568
  "homepage": "https://symfony.com",
2569
+ "time": "2019-11-03T17:17:59+00:00"
2570
  },
2571
  {
2572
  "name": "symfony/yaml",
2573
+ "version": "v3.4.36",
2574
  "source": {
2575
  "type": "git",
2576
  "url": "https://github.com/symfony/yaml.git",
2577
+ "reference": "dab657db15207879217fc81df4f875947bf68804"
2578
  },
2579
  "dist": {
2580
  "type": "zip",
2581
+ "url": "https://api.github.com/repos/symfony/yaml/zipball/dab657db15207879217fc81df4f875947bf68804",
2582
+ "reference": "dab657db15207879217fc81df4f875947bf68804",
2583
  "shasum": ""
2584
  },
2585
  "require": {
2625
  ],
2626
  "description": "Symfony Yaml Component",
2627
  "homepage": "https://symfony.com",
2628
+ "time": "2019-10-24T15:33:53+00:00"
2629
  },
2630
  {
2631
  "name": "webmozart/assert",
2632
+ "version": "1.6.0",
2633
  "source": {
2634
  "type": "git",
2635
  "url": "https://github.com/webmozart/assert.git",
2636
+ "reference": "573381c0a64f155a0d9a23f4b0c797194805b925"
2637
  },
2638
  "dist": {
2639
  "type": "zip",
2640
+ "url": "https://api.github.com/repos/webmozart/assert/zipball/573381c0a64f155a0d9a23f4b0c797194805b925",
2641
+ "reference": "573381c0a64f155a0d9a23f4b0c797194805b925",
2642
  "shasum": ""
2643
  },
2644
  "require": {
2645
  "php": "^5.3.3 || ^7.0",
2646
  "symfony/polyfill-ctype": "^1.8"
2647
  },
2648
+ "conflict": {
2649
+ "vimeo/psalm": "<3.6.0"
2650
+ },
2651
  "require-dev": {
2652
+ "phpunit/phpunit": "^4.8.36 || ^7.5.13"
 
2653
  },
2654
  "type": "library",
 
 
 
 
 
2655
  "autoload": {
2656
  "psr-4": {
2657
  "Webmozart\\Assert\\": "src/"
2673
  "check",
2674
  "validate"
2675
  ],
2676
+ "time": "2019-11-24T13:36:37+00:00"
2677
  },
2678
  {
2679
  "name": "wp-coding-standards/wpcs",
2680
+ "version": "2.2.0",
2681
  "source": {
2682
  "type": "git",
2683
  "url": "https://github.com/WordPress/WordPress-Coding-Standards.git",
2684
+ "reference": "f90e8692ce97b693633db7ab20bfa78d930f536a"
2685
  },
2686
  "dist": {
2687
  "type": "zip",
2688
+ "url": "https://api.github.com/repos/WordPress/WordPress-Coding-Standards/zipball/f90e8692ce97b693633db7ab20bfa78d930f536a",
2689
+ "reference": "f90e8692ce97b693633db7ab20bfa78d930f536a",
2690
  "shasum": ""
2691
  },
2692
  "require": {
2709
  "authors": [
2710
  {
2711
  "name": "Contributors",
2712
+ "homepage": "https://github.com/WordPress/WordPress-Coding-Standards/graphs/contributors"
2713
  }
2714
  ],
2715
  "description": "PHP_CodeSniffer rules (sniffs) to enforce WordPress coding conventions",
2718
  "standards",
2719
  "wordpress"
2720
  ],
2721
+ "time": "2019-11-11T12:34:03+00:00"
2722
  },
2723
  {
2724
  "name": "wpsh/local",
readme.txt CHANGED
@@ -3,22 +3,25 @@
3
  Contributors: kasparsd, jamescollins
4
  Tags: widget, widgets, widget context, context, logic, widget logic, visibility, widget visibility
5
  Requires at least: 3.0
6
- Tested up to: 5.2
7
- Stable tag: 1.2.0
8
  License: GPLv2 or later
9
  Requires PHP: 5.6
 
10
 
11
- Show or hide widgets on specific posts, pages and sections of your site.
12
 
13
 
14
  == Description ==
15
 
16
- Use [Widget Context](https://widgetcontext.com) to show or hide widgets on certain sections of your site -- front page, posts, pages, archives, search, etc. Use targeting by URLs (with wildcard support) for maximum flexibility.
17
 
 
18
 
19
- = Block Context =
20
 
21
- **New**: We've started working on the [Block Context plugin](https://blockcontext.com) which brings similar functionality to Gutenberg blocks.
 
 
22
 
23
 
24
  = Contribute =
@@ -30,14 +33,13 @@ Use [Widget Context](https://widgetcontext.com) to show or hide widgets on certa
30
 
31
  = Documentation =
32
 
33
- = Target by URL =
34
-
35
- The “Target by URL” is a very powerful feature with a lot of flexibility for targeting sections of your website based on the request URLs. It was inspired by a similar feature in the [Drupal CMS](https://www.drupal.org).
36
 
37
- - Use relative URLs such as `page/sub-page` instead of absolute URLs `https://example.com/page/sub-page`.
38
 
39
- - Relative are URLs more flexible and make the logic portable between different domains and server environments.
40
 
 
41
 
42
  = Wildcards =
43
 
@@ -49,6 +51,10 @@ Use the wildcard symbol `*` for matching dynamic parts of the URL. For example:
49
 
50
  - Use a trailing `?*` to capture URL with all query arguments such as `utm_source`, etc. For example, for every `blog/post-slug` also include `blog/post-slug?*`.
51
 
 
 
 
 
52
 
53
  == Installation ==
54
 
@@ -59,6 +65,11 @@ Use the wildcard symbol `*` for matching dynamic parts of the URL. For example:
59
 
60
  == Changelog ==
61
 
 
 
 
 
 
62
  = 1.2.0 (August 20, 2019) =
63
 
64
  - Set PHP 5.6 as the minimum supported version of PHP to match WordPress core.
3
  Contributors: kasparsd, jamescollins
4
  Tags: widget, widgets, widget context, context, logic, widget logic, visibility, widget visibility
5
  Requires at least: 3.0
6
+ Tested up to: 5.4
7
+ Stable tag: 1.3.0
8
  License: GPLv2 or later
9
  Requires PHP: 5.6
10
+ Donate link: https://widgetcontext.com/pro
11
 
12
+ Show and hide widgets on specific posts, pages and sections of your site.
13
 
14
 
15
  == Description ==
16
 
17
+ Use [Widget Context](https://widgetcontext.com) to show and hide widgets on certain sections of your site -- front page, posts, pages, archives, search, etc. Use targeting by URLs (with wildcard support) for maximum flexibility.
18
 
19
+ https://www.youtube.com/watch?v=rEHvqsWoXAE
20
 
 
21
 
22
+ = Premium Support =
23
+
24
+ Subscribe to our [Premium Support service](https://widgetcontext.com/pro) and get the PRO 🚀 version of the plugin for free when it’s launched! Your support enables consistent maintenance and new feature development, and is greatly appreciated.
25
 
26
 
27
  = Contribute =
33
 
34
  = Documentation =
35
 
36
+ Widget visibility can be configured under individual widget settings under "Appearance → Widgets" in your WordPress administration area or through the widget editing interface in the Customizer.
 
 
37
 
38
+ = Target by URL =
39
 
40
+ The "Target by URL" is a powerful feature for targeting sections of your website based on the request URLs. It was inspired by a similar feature in the [Drupal CMS](https://www.drupal.org).
41
 
42
+ Use relative URLs such as `page/sub-page` instead of absolute URLs `https://example.com/page/sub-page` because relative URLs are more flexible and make the logic portable between different domains and server environments.
43
 
44
  = Wildcards =
45
 
51
 
52
  - Use a trailing `?*` to capture URL with all query arguments such as `utm_source`, etc. For example, for every `blog/post-slug` also include `blog/post-slug?*`.
53
 
54
+ = Exclude by URL =
55
+
56
+ Specify URLs to ignore even if they're matched by any of the other context rules. For example, enter `example/sub-page` to hide a widget on this page even when "All Posts" is selected under "Global Sections".
57
+
58
 
59
  == Installation ==
60
 
65
 
66
  == Changelog ==
67
 
68
+ = 1.3.0 (April 23, 2020) =
69
+
70
+ - Introduce the long-awaited "Exclude by URL" feature to prevent certain URLs from showing or hiding a widget when it's matched by any other visibility rule.
71
+ - Introduce [premium support](https://widgetcontext.com/pro) to help maintain the plugin. Subscribe now to get the PRO version of the Widget Context for free when it's launched!
72
+
73
  = 1.2.0 (August 20, 2019) =
74
 
75
  - Set PHP 5.6 as the minimum supported version of PHP to match WordPress core.
src/Plugin.php CHANGED
@@ -165,7 +165,12 @@ class Plugin {
165
  static $meta;
166
 
167
  if ( ! isset( $meta ) ) {
168
- $meta = get_plugin_data( $this->file );
 
 
 
 
 
169
  }
170
 
171
  if ( isset( $field ) ) {
165
  static $meta;
166
 
167
  if ( ! isset( $meta ) ) {
168
+ $meta = get_file_data(
169
+ $this->file,
170
+ array(
171
+ 'Version' => 'Version',
172
+ )
173
+ );
174
  }
175
 
176
  if ( isset( $field ) ) {
src/UriRuleMatcher.php ADDED
@@ -0,0 +1,86 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Preseto\WidgetContext;
4
+
5
+ /**
6
+ * Match URI path regex-like rules.
7
+ */
8
+ class UriRuleMatcher {
9
+
10
+ /**
11
+ * Delimiter used in the regex expressions.
12
+ */
13
+ const DELIMITER = '/';
14
+
15
+ /**
16
+ * Map quoted regex patterns to actual regex patterns.
17
+ *
18
+ * @var array
19
+ */
20
+ const QUOTED_PATTERN_TO_REGEX = array(
21
+ '\*' => '.*', // Enable the wildcard selectors.
22
+ );
23
+
24
+ /**
25
+ * Helper to sanitize and format rules for regex.
26
+ *
27
+ * @param array $rules List of regex-like rules.
28
+ *
29
+ * @return array
30
+ */
31
+ protected function quote_rules( $rules ) {
32
+ return array_map(
33
+ function( $rule ) {
34
+ // Escape regex chars before we enable back the wildcards.
35
+ $rule = preg_quote( $rule, self::DELIMITER ); // Note that '/' is the delimiter we're using for the final expression below.
36
+
37
+ // Enable the wildcard checks.
38
+ return str_replace(
39
+ array_keys( self::QUOTED_PATTERN_TO_REGEX ),
40
+ self::QUOTED_PATTERN_TO_REGEX,
41
+ $rule
42
+ );
43
+ },
44
+ $rules
45
+ );
46
+ }
47
+
48
+ /**
49
+ * Build a regex pattern for any set of rules.
50
+ *
51
+ * @param array $rules List of regular expression rules to match.
52
+ *
53
+ * @return string
54
+ */
55
+ protected function rules_to_expression( $rules ) {
56
+ $rules = array_map(
57
+ function ( $rule ) {
58
+ return sprintf( '(%s$)', $rule );
59
+ },
60
+ $this->quote_rules( $rules )
61
+ );
62
+
63
+ return sprintf(
64
+ '%s^(%s)%si',
65
+ self::DELIMITER,
66
+ implode( '|', $rules ),
67
+ self::DELIMITER
68
+ );
69
+ }
70
+
71
+ /**
72
+ * Check if a path matches the regex rules.
73
+ *
74
+ * @param string $uri Path to check.
75
+ * @param array $rules List of URIs to check against.
76
+ *
77
+ * @return boolean
78
+ */
79
+ public function uri_matches_rules( $uri, $rules ) {
80
+ if ( ! empty( $rules ) ) {
81
+ return (bool) preg_match( $this->rules_to_expression( $rules ), $uri );
82
+ }
83
+
84
+ return false;
85
+ }
86
+ }
src/UriRules.php ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Preseto\WidgetContext;
4
+
5
+ /**
6
+ * URL path rules.
7
+ */
8
+ class UriRules {
9
+
10
+ /**
11
+ * Keep all the rules.
12
+ *
13
+ * @var array
14
+ */
15
+ private $rules = array();
16
+
17
+ /**
18
+ * Setup the pattern matcher.
19
+ *
20
+ * @param array $patterns List of regex-like match patterns.
21
+ */
22
+ public function __construct( $rules ) {
23
+ $this->rules = array_map( 'trim', $rules );
24
+ }
25
+
26
+ /**
27
+ * Return the URIs.
28
+ *
29
+ * @return array List of URIs.
30
+ */
31
+ public function rules() {
32
+ return $this->rules;
33
+ }
34
+
35
+ /**
36
+ * Check if any of the rules demand query string matching.
37
+ *
38
+ * @return boolean
39
+ */
40
+ public function has_rules_with_query_strings() {
41
+ foreach ( $this->rules as $rule ) {
42
+ if ( false !== strpos( $rule, '?' ) ) {
43
+ return true;
44
+ }
45
+ }
46
+
47
+ return false;
48
+ }
49
+ }
src/WidgetContext.php CHANGED
@@ -1,10 +1,20 @@
1
  <?php
2
 
 
 
 
3
  /**
4
  * Widget Context plugin core.
5
  */
6
  class WidgetContext {
7
 
 
 
 
 
 
 
 
8
  private $sidebars_widgets;
9
  private $options_name = 'widget_logic_options'; // Context settings for widgets (visibility, etc)
10
  private $settings_name = 'widget_context_settings'; // Widget Context global settings
@@ -114,23 +124,28 @@ class WidgetContext {
114
  ),
115
  'location' => array(
116
  'label' => __( 'Global Sections', 'widget-context' ),
117
- 'description' => __( 'Based on standard WordPress template tags.', 'widget-context' ),
118
  'weight' => 10,
119
  ),
120
  'url' => array(
121
  'label' => __( 'Target by URL', 'widget-context' ),
122
- 'description' => __( 'Based on URL patterns.', 'widget-context' ),
123
  'weight' => 20,
124
  ),
 
 
 
 
 
125
  'admin_notes' => array(
126
  'label' => __( 'Notes (invisible to public)', 'widget-context' ),
127
- 'description' => __( 'Enables private notes on widget context settings.', 'widget-context' ),
128
  'weight' => 90,
129
  ),
130
  );
131
 
132
  // Add default context controls and checks
133
- foreach ( $default_contexts as $context_name => $context_desc ) {
134
  add_filter( 'widget_context_control-' . $context_name, array( $this, 'control_' . $context_name ), 10, 2 );
135
  add_filter( 'widget_context_check-' . $context_name, array( $this, 'context_check_' . $context_name ), 10, 2 );
136
  }
@@ -187,6 +202,16 @@ class WidgetContext {
187
  }
188
 
189
 
 
 
 
 
 
 
 
 
 
 
190
  function set_widget_contexts_frontend() {
191
  // Hide/show widgets for is_active_sidebar() to work
192
  add_filter( 'sidebars_widgets', array( $this, 'maybe_unset_widgets_by_context' ), 10 );
@@ -195,7 +220,7 @@ class WidgetContext {
195
 
196
  function admin_scripts( $page ) {
197
  // Enqueue only on widgets and customizer view
198
- if ( ! in_array( $page, array( 'widgets.php', 'settings_page_widget_context_settings' ), true ) ) {
199
  return;
200
  }
201
 
@@ -289,13 +314,61 @@ class WidgetContext {
289
  return $sidebars_widgets;
290
  }
291
 
292
-
293
- function check_widget_visibility( $widget_id ) {
294
- // Check if this widget even has context set
 
 
 
 
 
 
295
  if ( ! isset( $this->context_options[ $widget_id ] ) ) {
296
  return true;
297
  }
298
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
299
  $matches = array();
300
 
301
  foreach ( $this->get_contexts() as $context_id => $context_settings ) {
@@ -304,10 +377,10 @@ class WidgetContext {
304
  continue;
305
  }
306
 
 
 
307
  // Make sure that context settings for this widget are defined
308
- if ( ! isset( $this->context_options[ $widget_id ][ $context_id ] ) ) {
309
- $widget_context_args = array();
310
- } else {
311
  $widget_context_args = $this->context_options[ $widget_id ][ $context_id ];
312
  }
313
 
@@ -318,29 +391,7 @@ class WidgetContext {
318
  );
319
  }
320
 
321
- // Get the match rule for this widget (show/hide/selected/notselected)
322
- $match_rule = $this->context_options[ $widget_id ]['incexc']['condition'];
323
-
324
- // Force show or hide the widget!
325
- if ( 'show' === $match_rule ) {
326
- return true;
327
- } elseif ( 'hide' === $match_rule ) {
328
- return false;
329
- }
330
-
331
- $inc = false;
332
-
333
- if ( 'selected' === $match_rule ) {
334
- $inc = true;
335
- }
336
-
337
- if ( $inc && in_array( true, $matches, true ) ) {
338
- return true;
339
- } elseif ( ! $inc && ! in_array( true, $matches, true ) ) {
340
- return true;
341
- }
342
-
343
- return false;
344
  }
345
 
346
 
@@ -382,43 +433,82 @@ class WidgetContext {
382
  return $check;
383
  }
384
 
385
-
386
  /**
387
- * Conditional logic for the URL check.
388
  *
389
- * @param bool $check Current visibility state.
390
- * @param array $settings Visibility settings.
391
  *
392
- * @return bool
393
  */
394
- function context_check_url( $check, $settings ) {
395
- static $path;
 
 
396
 
397
  $settings = wp_parse_args(
398
  $settings,
399
  array(
400
- 'urls' => null,
401
  )
402
  );
403
 
404
- $urls = trim( $settings['urls'] );
 
405
 
406
- if ( empty( $urls ) ) {
407
- return $check;
408
- }
 
 
 
 
 
 
 
 
409
 
410
- if ( ! isset( $path ) ) {
411
- // Do the parsing only once.
412
- $path = $this->get_request_path( $_SERVER['REQUEST_URI'] );
413
  }
414
 
415
- if ( $this->match_path( $path, $urls ) ) {
416
- return true;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
417
  }
418
 
419
  return $check;
420
  }
421
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
422
  /**
423
  * Return the path relative to the root of the hostname. We always remove
424
  * the leading and trailing slashes around the URI path.
@@ -427,7 +517,7 @@ class WidgetContext {
427
  *
428
  * @return string
429
  */
430
- public function get_request_path( $uri ) {
431
  $parts = wp_parse_args(
432
  wp_parse_url( $uri ),
433
  array(
@@ -445,60 +535,53 @@ class WidgetContext {
445
  }
446
 
447
  /**
448
- * Check if the current request matches path rules.
449
  *
450
- * @param string $path Current request relative to the root of the hostname.
451
- * @param string $rules A list of path patterns seperated by new line.
452
  *
453
- * @return bool
454
  */
455
- function match_path( $path, $rules ) {
456
- $path_only = strtok( $path, '?' );
457
- $patterns = explode( "\n", $rules );
458
-
459
- foreach ( $patterns as &$pattern ) {
460
- // Use the same logic for parsing the visibility rules.
461
- $pattern = $this->get_request_path( trim( $pattern ) );
462
- }
463
-
464
- // Remove empty patterns.
465
- $patterns = array_filter( $patterns );
466
-
467
- // Match against the path with and without the query string.
468
- if ( $this->path_matches_patterns( $path, $patterns ) || $this->path_matches_patterns( $path_only, $patterns ) ) {
469
- return true;
470
- }
471
 
472
- return false;
473
  }
474
 
475
  /**
476
- * Check if a URI path matches a set of regex patterns.
477
  *
478
- * @param string $path Request URI.
479
- * @param array $patterns A list of patterns.
480
  *
481
- * @return bool
482
  */
483
- public function path_matches_patterns( $path, $patterns ) {
484
- if ( empty( $patterns ) ) {
485
- return false;
 
 
 
 
 
 
 
486
  }
487
 
488
- foreach ( $patterns as &$pattern ) {
489
- // Escape regex chars since we only support wildcards.
490
- $pattern = preg_quote( trim( $pattern ), '/' );
491
 
492
- // Enable wildcard checks.
493
- $pattern = str_replace( '\*', '.*', $pattern );
494
  }
495
 
496
- $regex = sprintf(
497
- '/^(%s)$/i',
498
- implode( '|', $patterns )
499
- );
500
-
501
- return (bool) preg_match( $regex, $path );
502
  }
503
 
504
 
@@ -578,7 +661,7 @@ class WidgetContext {
578
  sprintf(
579
  /* translators: %s is a URL to the settings page. */
580
  __( 'No widget controls enabled. You can enable them in <a href="%s">Widget Context settings</a>.', 'widget-context' ),
581
- admin_url( 'options-general.php?page=widget_context_settings' )
582
  )
583
  ),
584
  );
@@ -592,29 +675,36 @@ class WidgetContext {
592
  }
593
  }
594
 
595
- $settings_link = '';
596
 
597
  if ( current_user_can( 'edit_theme_options' ) ) {
598
- $settings_link = sprintf(
599
- '<a href="%s" class="widget-context-settings-link" title="%s">%s</a>',
600
  admin_url( 'options-general.php?page=widget_context_settings' ),
601
  esc_attr__( 'Widget Context Settings', 'widget-context' ),
602
  esc_html__( 'Settings', 'widget-context' )
603
  );
 
 
 
 
 
 
 
604
  }
605
 
606
  return sprintf(
607
  '<div class="widget-context">
608
  <div class="widget-context-header">
609
  <h3>%s</h3>
610
- %s
611
  </div>
612
  <div class="widget-context-inside" id="widget-context-%s" data-widget-id="%s">
613
  %s
614
  </div>
615
  </div>',
616
  __( 'Widget Context', 'widget-context' ),
617
- $settings_link,
618
  // Inslide classes
619
  esc_attr( $widget_id ),
620
  esc_attr( $widget_id ),
@@ -670,7 +760,17 @@ class WidgetContext {
670
  '<div>%s</div>
671
  <p class="help">%s</p>',
672
  $this->make_simple_textarea( $control_args, 'urls' ),
673
- __( 'Enter one location fragment per line. Use <strong>*</strong> character as a wildcard. Example: <code>category/peace/*</code> to target all posts in category <em>peace</em>.', 'widget-context' )
 
 
 
 
 
 
 
 
 
 
674
  );
675
  }
676
 
@@ -906,12 +1006,13 @@ class WidgetContext {
906
 
907
 
908
  function widget_context_settings_menu() {
909
- add_options_page(
910
  __( 'Widget Context Settings', 'widget-context' ),
911
  __( 'Widget Context', 'widget-context' ),
912
  'manage_options',
913
  $this->settings_name,
914
- array( $this, 'widget_context_admin_view' )
 
915
  );
916
  }
917
 
@@ -921,6 +1022,26 @@ class WidgetContext {
921
  }
922
 
923
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
924
  function widget_context_admin_view() {
925
  $context_controls = array();
926
 
@@ -932,7 +1053,7 @@ class WidgetContext {
932
 
933
  if ( ! empty( $context_args['description'] ) ) {
934
  $context_description = sprintf(
935
- '<p class="context-desc">%s</p>',
936
  esc_html( $context_args['description'] )
937
  );
938
  } else {
@@ -945,7 +1066,7 @@ class WidgetContext {
945
  }
946
 
947
  $context_controls[] = sprintf(
948
- '<li class="context-%s">
949
  <label>
950
  <input type="hidden" name="%s[contexts][%s]" value="0" />
951
  <input type="checkbox" name="%s[contexts][%s]" value="1" %s /> %s
@@ -976,16 +1097,43 @@ class WidgetContext {
976
  do_settings_sections( $this->settings_name );
977
  ?>
978
 
979
- <?php
980
- printf(
981
- '<div class="settings-section settings-section-modules">
982
- <h3>%s</h3>
983
- <ul>%s</ul>
984
- </div>',
985
- esc_html__( 'Enabled Context Modules', 'widget-context' ),
986
- implode( '', $context_controls )
987
- );
988
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
989
 
990
  <?php
991
  submit_button();
1
  <?php
2
 
3
+ use Preseto\WidgetContext\UriRuleMatcher;
4
+ use Preseto\WidgetContext\UriRules;
5
+
6
  /**
7
  * Widget Context plugin core.
8
  */
9
  class WidgetContext {
10
 
11
+ /**
12
+ * Rule ID for the invert by URL.
13
+ *
14
+ * @var string
15
+ */
16
+ const RULE_KEY_URLS_INVERT = 'urls_invert';
17
+
18
  private $sidebars_widgets;
19
  private $options_name = 'widget_logic_options'; // Context settings for widgets (visibility, etc)
20
  private $settings_name = 'widget_context_settings'; // Widget Context global settings
124
  ),
125
  'location' => array(
126
  'label' => __( 'Global Sections', 'widget-context' ),
127
+ 'description' => __( 'Match using the standard WordPress template tags.', 'widget-context' ),
128
  'weight' => 10,
129
  ),
130
  'url' => array(
131
  'label' => __( 'Target by URL', 'widget-context' ),
132
+ 'description' => __( 'Match using URL patterns.', 'widget-context' ),
133
  'weight' => 20,
134
  ),
135
+ self::RULE_KEY_URLS_INVERT => array(
136
+ 'label' => __( 'Exclude by URL', 'widget-context' ),
137
+ 'description' => __( 'Override other matches using URL patterns.', 'widget-context' ),
138
+ 'weight' => 25,
139
+ ),
140
  'admin_notes' => array(
141
  'label' => __( 'Notes (invisible to public)', 'widget-context' ),
142
+ 'description' => __( 'Keep private notes on widget context settings.', 'widget-context' ),
143
  'weight' => 90,
144
  ),
145
  );
146
 
147
  // Add default context controls and checks
148
+ foreach ( array_keys( $default_contexts ) as $context_name ) {
149
  add_filter( 'widget_context_control-' . $context_name, array( $this, 'control_' . $context_name ), 10, 2 );
150
  add_filter( 'widget_context_check-' . $context_name, array( $this, 'context_check_' . $context_name ), 10, 2 );
151
  }
202
  }
203
 
204
 
205
+ /**
206
+ * Get the state of the PRO nag.
207
+ *
208
+ * @return boolean
209
+ */
210
+ public function pro_nag_enabled() {
211
+ return (bool) apply_filters( 'widget_context_pro_nag', true );
212
+ }
213
+
214
+
215
  function set_widget_contexts_frontend() {
216
  // Hide/show widgets for is_active_sidebar() to work
217
  add_filter( 'sidebars_widgets', array( $this, 'maybe_unset_widgets_by_context' ), 10 );
220
 
221
  function admin_scripts( $page ) {
222
  // Enqueue only on widgets and customizer view
223
+ if ( ! in_array( $page, array( 'widgets.php', 'appearance_page_widget_context_settings' ), true ) ) {
224
  return;
225
  }
226
 
314
  return $sidebars_widgets;
315
  }
316
 
317
+ /**
318
+ * Determine widget visibility according to the current global context.
319
+ *
320
+ * @param string $widget_id Widget ID.
321
+ *
322
+ * @return boolean
323
+ */
324
+ public function check_widget_visibility( $widget_id ) {
325
+ // Check if this widget even has context set.
326
  if ( ! isset( $this->context_options[ $widget_id ] ) ) {
327
  return true;
328
  }
329
 
330
+ // Get the match rule for this widget (show/hide/selected/notselected).
331
+ $match_rule = $this->context_options[ $widget_id ]['incexc']['condition'];
332
+
333
+ // Force show or hide the widget!
334
+ if ( 'show' === $match_rule ) {
335
+ return true;
336
+ } elseif ( 'hide' === $match_rule ) {
337
+ return false;
338
+ }
339
+
340
+ // Show or hide on match.
341
+ $condition = ( 'selected' === $match_rule );
342
+
343
+ if ( $this->context_matches_condition_for_widget_id( $widget_id ) ) {
344
+ return $condition;
345
+ }
346
+
347
+ return ! $condition;
348
+ }
349
+
350
+ /**
351
+ * Check if widget visibility rules match the current context.
352
+ *
353
+ * @param string $widget_id Widget ID.
354
+ *
355
+ * @return boolean
356
+ */
357
+ public function context_matches_condition_for_widget_id( $widget_id ) {
358
+ $matches = $this->context_matches_for_widget_id( $widget_id );
359
+
360
+ // Inverted rules can only override another positive match.
361
+ return ( in_array( true, $matches, true ) && ! in_array( false, $matches, true ) );
362
+ }
363
+
364
+ /**
365
+ * Get context rule matches for a widget ID.
366
+ *
367
+ * @param string $widget_id Widget ID.
368
+ *
369
+ * @return array
370
+ */
371
+ public function context_matches_for_widget_id( $widget_id ) {
372
  $matches = array();
373
 
374
  foreach ( $this->get_contexts() as $context_id => $context_settings ) {
377
  continue;
378
  }
379
 
380
+ $widget_context_args = array();
381
+
382
  // Make sure that context settings for this widget are defined
383
+ if ( ! empty( $this->context_options[ $widget_id ][ $context_id ] ) ) {
 
 
384
  $widget_context_args = $this->context_options[ $widget_id ][ $context_id ];
385
  }
386
 
391
  );
392
  }
393
 
394
+ return $matches;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
395
  }
396
 
397
 
433
  return $check;
434
  }
435
 
 
436
  /**
437
+ * Fetch a setting value for the context setting as a string.
438
  *
439
+ * @param array $settings List of all settings by setting key.
440
+ * @param string $key Setting key to check.
441
  *
442
+ * @return string
443
  */
444
+ protected function get_setting_as_string( $settings, $key ) {
445
+ if ( ! is_array( $settings ) ) {
446
+ $settings = array();
447
+ }
448
 
449
  $settings = wp_parse_args(
450
  $settings,
451
  array(
452
+ $key => null,
453
  )
454
  );
455
 
456
+ return trim( (string) $settings[ $key ] );
457
+ }
458
 
459
+ /**
460
+ * Check if a set of URL paths match the current request.
461
+ *
462
+ * @param bool $check Current visibility state.
463
+ * @param array $settings Visibility settings.
464
+ *
465
+ * @return bool
466
+ */
467
+ public function context_check_url( $check, $settings ) {
468
+ $path = $this->get_request_path();
469
+ $urls = $this->get_setting_as_string( $settings, 'urls' );
470
 
471
+ if ( ! empty( $urls ) && $this->match_path( $path, $urls ) ) {
472
+ return true;
 
473
  }
474
 
475
+ return $check;
476
+ }
477
+
478
+ /**
479
+ * Check if a set of URL paths match the current request.
480
+ *
481
+ * @param bool $check Current visibility state.
482
+ * @param array $settings Visibility settings.
483
+ *
484
+ * @return bool
485
+ */
486
+ public function context_check_urls_invert( $check, $settings ) {
487
+ $path = $this->get_request_path();
488
+ $urls = $this->get_setting_as_string( $settings, self::RULE_KEY_URLS_INVERT );
489
+
490
+ if ( ! empty( $urls ) && $this->match_path( $path, $urls ) ) {
491
+ return false; // Override any positive matches.
492
  }
493
 
494
  return $check;
495
  }
496
 
497
+ /**
498
+ * Fetch the request path for the current request.
499
+ *
500
+ * @return string
501
+ */
502
+ protected function get_request_path() {
503
+ static $path;
504
+
505
+ if ( ! isset( $path ) ) {
506
+ $path = $this->path_from_uri( $_SERVER['REQUEST_URI'] );
507
+ }
508
+
509
+ return $path;
510
+ }
511
+
512
  /**
513
  * Return the path relative to the root of the hostname. We always remove
514
  * the leading and trailing slashes around the URI path.
517
  *
518
  * @return string
519
  */
520
+ public function path_from_uri( $uri ) {
521
  $parts = wp_parse_args(
522
  wp_parse_url( $uri ),
523
  array(
535
  }
536
 
537
  /**
538
+ * Parse a text blob of URI fragments into URI rules.
539
  *
540
+ * @param string $paths String of URI paths seperated by line breaks.
 
541
  *
542
+ * @return array List of formatted URI paths.
543
  */
544
+ protected function uri_rules_from_paths( $paths ) {
545
+ $patterns = explode( "\n", $paths );
546
+
547
+ $patterns = array_map(
548
+ function( $pattern ) {
549
+ // Resolve rule paths the same way as the request URI.
550
+ return $this->path_from_uri( trim( $pattern ) );
551
+ },
552
+ $patterns
553
+ );
 
 
 
 
 
 
554
 
555
+ return array_filter( $patterns );
556
  }
557
 
558
  /**
559
+ * Check if the current request matches path rules.
560
  *
561
+ * @param string $path Current request relative to the root of the hostname.
562
+ * @param string $rules A list of path patterns seperated by new line.
563
  *
564
+ * @return bool|null Return `null` if no rules to match against.
565
  */
566
+ public function match_path( $path, $rules ) {
567
+ $uri_rules = new UriRules( $this->uri_rules_from_paths( $rules ) );
568
+ $uri_rules_paths = $uri_rules->rules();
569
+
570
+ /**
571
+ * Ignore query parameters in path unless any of the rules actually use them.
572
+ * Defaults to matching paths with any query parameters.
573
+ */
574
+ if ( ! $uri_rules->has_rules_with_query_strings() ) {
575
+ $path = strtok( $path, '?' );
576
  }
577
 
578
+ if ( ! empty( $uri_rules_paths ) ) {
579
+ $matcher = new UriRuleMatcher();
 
580
 
581
+ return $matcher->uri_matches_rules( $path, $uri_rules_paths );
 
582
  }
583
 
584
+ return null;
 
 
 
 
 
585
  }
586
 
587
 
661
  sprintf(
662
  /* translators: %s is a URL to the settings page. */
663
  __( 'No widget controls enabled. You can enable them in <a href="%s">Widget Context settings</a>.', 'widget-context' ),
664
+ $this->plugin_settings_admin_url()
665
  )
666
  ),
667
  );
675
  }
676
  }
677
 
678
+ $settings_link = array();
679
 
680
  if ( current_user_can( 'edit_theme_options' ) ) {
681
+ $settings_link[] = sprintf(
682
+ '<a href="%s" title="%s" target="_blank">%s</a>',
683
  admin_url( 'options-general.php?page=widget_context_settings' ),
684
  esc_attr__( 'Widget Context Settings', 'widget-context' ),
685
  esc_html__( 'Settings', 'widget-context' )
686
  );
687
+
688
+ if ( $this->pro_nag_enabled() ) {
689
+ $settings_link[] = sprintf(
690
+ '<a href="%s" target="_blank">PRO 🚀</a>',
691
+ esc_url( 'https://widgetcontext.com/pro' )
692
+ );
693
+ }
694
  }
695
 
696
  return sprintf(
697
  '<div class="widget-context">
698
  <div class="widget-context-header">
699
  <h3>%s</h3>
700
+ <span class="widget-context-settings-link">%s</span>
701
  </div>
702
  <div class="widget-context-inside" id="widget-context-%s" data-widget-id="%s">
703
  %s
704
  </div>
705
  </div>',
706
  __( 'Widget Context', 'widget-context' ),
707
+ implode( ' | ', $settings_link ),
708
  // Inslide classes
709
  esc_attr( $widget_id ),
710
  esc_attr( $widget_id ),
760
  '<div>%s</div>
761
  <p class="help">%s</p>',
762
  $this->make_simple_textarea( $control_args, 'urls' ),
763
+ __( 'Enter one location fragment per line. Use <strong>*</strong> character as a wildcard. Example: <code>page/example</code> to target a specific page or <code>page/*</code> to target all children of a page.', 'widget-context' )
764
+ );
765
+ }
766
+
767
+
768
+ function control_urls_invert( $control_args ) {
769
+ return sprintf(
770
+ '<div>%s</div>
771
+ <p class="help">%s</p>',
772
+ $this->make_simple_textarea( $control_args, self::RULE_KEY_URLS_INVERT ),
773
+ __( 'Specify URLs to override the Target by URLs settings. Useful for excluding specific URLs when using wildcards in Target by URL.', 'widget-context' )
774
  );
775
  }
776
 
1006
 
1007
 
1008
  function widget_context_settings_menu() {
1009
+ add_theme_page(
1010
  __( 'Widget Context Settings', 'widget-context' ),
1011
  __( 'Widget Context', 'widget-context' ),
1012
  'manage_options',
1013
  $this->settings_name,
1014
+ array( $this, 'widget_context_admin_view' ),
1015
+ 3 // Try to place it right under the Widgets.
1016
  );
1017
  }
1018
 
1022
  }
1023
 
1024
 
1025
+ /**
1026
+ * Return a link to the Customize Widgets admin page.
1027
+ *
1028
+ * @return string
1029
+ */
1030
+ public function customize_widgets_admin_url() {
1031
+ return admin_url( 'customize.php?autofocus[panel]=widgets' );
1032
+ }
1033
+
1034
+
1035
+ /**
1036
+ * Get the URL to the plugin settings page.
1037
+ *
1038
+ * @return string
1039
+ */
1040
+ public function plugin_settings_admin_url() {
1041
+ return admin_url( 'themes.php?page=widget_context_settings' );
1042
+ }
1043
+
1044
+
1045
  function widget_context_admin_view() {
1046
  $context_controls = array();
1047
 
1053
 
1054
  if ( ! empty( $context_args['description'] ) ) {
1055
  $context_description = sprintf(
1056
+ '<p class="description">%s</p>',
1057
  esc_html( $context_args['description'] )
1058
  );
1059
  } else {
1066
  }
1067
 
1068
  $context_controls[] = sprintf(
1069
+ '<li class="enabled-contexts-item context-%s">
1070
  <label>
1071
  <input type="hidden" name="%s[contexts][%s]" value="0" />
1072
  <input type="checkbox" name="%s[contexts][%s]" value="1" %s /> %s
1097
  do_settings_sections( $this->settings_name );
1098
  ?>
1099
 
1100
+ <table class="form-table" role="presentation">
1101
+ <tr id="widget-context-pro">
1102
+ <th scrope="row">
1103
+ <?php esc_html_e( 'Support', 'widget-context' ); ?>
1104
+ </th>
1105
+ <td>
1106
+ <p>
1107
+ <a href="https://widgetcontext.com/pro">Subscribe to get premium support</a> and the 🚀 PRO version of the plugin for free when it's launched!
1108
+ Your support enables consistent maintenance and new feature development, and is greatly appreciated.
1109
+ </p>
1110
+ </td>
1111
+ </tr>
1112
+ <tr>
1113
+ <th scrope="row">
1114
+ <?php esc_html_e( 'Configure Widgets', 'widget-context' ); ?>
1115
+ </th>
1116
+ <td>
1117
+ <p>
1118
+ <a class="button button-primary" href="<?php echo esc_url( $this->customize_widgets_admin_url() ); ?>"><?php esc_html_e( 'Configure Widgets', 'widget-context' ); ?></a>
1119
+ </p>
1120
+ <p class="description">
1121
+ <?php esc_html_e( 'Configure widget context using the WordPress Customizer (with preview) or using the widget settings under "Appearance → Widgets".', 'widget-context' ); ?>
1122
+ </p>
1123
+ </td>
1124
+ </tr>
1125
+ <tr>
1126
+ <th scrope="row">
1127
+ <?php esc_html_e( 'Enabled Contexts', 'widget-context' ); ?>
1128
+ </th>
1129
+ <td>
1130
+ <p>
1131
+ <?php esc_html_e( 'Select the context rules available for all widgets and hide the unused ones:', 'widget-context' ); ?>
1132
+ </p>
1133
+ <?php printf( '<ul>%s</ul>', implode( '', $context_controls ) ); ?>
1134
+ </td>
1135
+ </tr>
1136
+ </table>
1137
 
1138
  <?php
1139
  submit_button();
src/modules/custom-post-types-taxonomies/module.php CHANGED
@@ -47,7 +47,7 @@ class WidgetContextCustomCptTax {
47
  function add_context( $contexts ) {
48
  $contexts['custom_post_types_taxonomies'] = array(
49
  'label' => __( 'Custom Post Types and Taxonomies', 'widget-context' ),
50
- 'description' => __( 'Context based custom post types and taxonomies', 'widget-context' ),
51
  'weight' => 10,
52
  );
53
 
47
  function add_context( $contexts ) {
48
  $contexts['custom_post_types_taxonomies'] = array(
49
  'label' => __( 'Custom Post Types and Taxonomies', 'widget-context' ),
50
+ 'description' => __( 'Match posts and archives of custom post types and taxonomies.', 'widget-context' ),
51
  'weight' => 10,
52
  );
53
 
src/modules/word-count/module.php CHANGED
@@ -25,7 +25,7 @@ class WidgetContextWordCount {
25
  function add_word_count_context( $contexts ) {
26
  $contexts['word_count'] = array(
27
  'label' => __( 'Word Count', 'widget-context' ),
28
- 'description' => __( 'Context based on word count on the page.', 'widget-context' ),
29
  'weight' => 15,
30
  );
31
 
25
  function add_word_count_context( $contexts ) {
26
  $contexts['word_count'] = array(
27
  'label' => __( 'Word Count', 'widget-context' ),
28
+ 'description' => __( 'Match based on the post and page word count.', 'widget-context' ),
29
  'weight' => 15,
30
  );
31
 
vendor/composer/autoload_classmap.php CHANGED
@@ -7,6 +7,8 @@ $baseDir = dirname($vendorDir);
7
 
8
  return array(
9
  'Preseto\\WidgetContext\\Plugin' => $baseDir . '/src/Plugin.php',
 
 
10
  'WidgetContext' => $baseDir . '/src/WidgetContext.php',
11
  'WidgetContextCustomCptTax' => $baseDir . '/src/modules/custom-post-types-taxonomies/module.php',
12
  'WidgetContextWordCount' => $baseDir . '/src/modules/word-count/module.php',
7
 
8
  return array(
9
  'Preseto\\WidgetContext\\Plugin' => $baseDir . '/src/Plugin.php',
10
+ 'Preseto\\WidgetContext\\UriRuleMatcher' => $baseDir . '/src/UriRuleMatcher.php',
11
+ 'Preseto\\WidgetContext\\UriRules' => $baseDir . '/src/UriRules.php',
12
  'WidgetContext' => $baseDir . '/src/WidgetContext.php',
13
  'WidgetContextCustomCptTax' => $baseDir . '/src/modules/custom-post-types-taxonomies/module.php',
14
  'WidgetContextWordCount' => $baseDir . '/src/modules/word-count/module.php',
vendor/composer/autoload_real.php CHANGED
@@ -13,6 +13,9 @@ class ComposerAutoloaderInit6e573a37469c9353164f8e0a8d8c8254
13
  }
14
  }
15
 
 
 
 
16
  public static function getLoader()
17
  {
18
  if (null !== self::$loader) {
13
  }
14
  }
15
 
16
+ /**
17
+ * @return \Composer\Autoload\ClassLoader
18
+ */
19
  public static function getLoader()
20
  {
21
  if (null !== self::$loader) {
vendor/composer/autoload_static.php CHANGED
@@ -8,6 +8,8 @@ class ComposerStaticInit6e573a37469c9353164f8e0a8d8c8254
8
  {
9
  public static $classMap = array (
10
  'Preseto\\WidgetContext\\Plugin' => __DIR__ . '/../..' . '/src/Plugin.php',
 
 
11
  'WidgetContext' => __DIR__ . '/../..' . '/src/WidgetContext.php',
12
  'WidgetContextCustomCptTax' => __DIR__ . '/../..' . '/src/modules/custom-post-types-taxonomies/module.php',
13
  'WidgetContextWordCount' => __DIR__ . '/../..' . '/src/modules/word-count/module.php',
8
  {
9
  public static $classMap = array (
10
  'Preseto\\WidgetContext\\Plugin' => __DIR__ . '/../..' . '/src/Plugin.php',
11
+ 'Preseto\\WidgetContext\\UriRuleMatcher' => __DIR__ . '/../..' . '/src/UriRuleMatcher.php',
12
+ 'Preseto\\WidgetContext\\UriRules' => __DIR__ . '/../..' . '/src/UriRules.php',
13
  'WidgetContext' => __DIR__ . '/../..' . '/src/WidgetContext.php',
14
  'WidgetContextCustomCptTax' => __DIR__ . '/../..' . '/src/modules/custom-post-types-taxonomies/module.php',
15
  'WidgetContextWordCount' => __DIR__ . '/../..' . '/src/modules/word-count/module.php',
widget-context.php CHANGED
@@ -2,8 +2,8 @@
2
  /**
3
  * Plugin Name: Widget Context
4
  * Plugin URI: https://widgetcontext.com
5
- * Description: Show or hide widgets depending on the section of the site that is being viewed.
6
- * Version: 1.2.0
7
  * Author: Kaspars Dambis
8
  * Author URI: https://widgetcontext.com
9
  * Text Domain: widget-context
2
  /**
3
  * Plugin Name: Widget Context
4
  * Plugin URI: https://widgetcontext.com
5
+ * Description: Show or hide widgets depending on the section of the site that is being viewed. Configure the widget visibility rules under the individual widget settings.
6
+ * Version: 1.3.0
7
  * Author: Kaspars Dambis
8
  * Author URI: https://widgetcontext.com
9
  * Text Domain: widget-context