Custom Facebook Feed - Version 2.12

Version Description

  • New: Added a backup cache so the feed will still display even if there's an error from the Facebook API.
  • New: You can now easily manage multiple page or group accounts on the plugin settings page allowing you to easily add them to other feeds on your site. When you connect a page or group you will now see it listed in the "Connected Accounts" section. You can add it to the primary feed or to another feed by using the new account shortcode option.
  • Tweak: Added a filter which can be used to filter the API data when returned; cff_filter_api_data.
  • Tweak: Updated API error messages
  • Fix: Fixed an issue with some @tag links in post text due to a Facebook API change
  • Fix: Fixed a rare issue with ellipsis chracter symbols in shared link descriptions causing the entire link description not to be displayed
Download this release

Release Info

Developer smashballoon
Plugin Icon 128x128 Custom Facebook Feed
Version 2.12
Comparing to
See all releases

Code changes from version 2.11.1 to 2.12

README.txt CHANGED
@@ -3,8 +3,8 @@ Contributors: smashballoon
3
  Tags: Facebook, Facebook feed, Facebook posts, Facebook wall, Facebook page
4
  Requires at least: 3.0
5
  Requires PHP: 5.2
6
- Tested up to: 5.2
7
- Stable tag: 2.11.1
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
@@ -255,6 +255,14 @@ The most common reason for this is that an add-on or extension you have installe
255
  9. It's super easy to display your Facebook feed in any page or post
256
 
257
  == Changelog ==
 
 
 
 
 
 
 
 
258
  = 2.11.1 =
259
  * Tweak: Added the link source URL below the title for shared link posts
260
  * Fix: Some themes would prevent the "Share" link from working successfully
3
  Tags: Facebook, Facebook feed, Facebook posts, Facebook wall, Facebook page
4
  Requires at least: 3.0
5
  Requires PHP: 5.2
6
+ Tested up to: 5.3
7
+ Stable tag: 2.12
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
255
  9. It's super easy to display your Facebook feed in any page or post
256
 
257
  == Changelog ==
258
+ = 2.12 =
259
+ * New: Added a backup cache so the feed will still display even if there's an error from the Facebook API.
260
+ * New: You can now easily manage multiple page or group accounts on the plugin settings page allowing you to easily add them to other feeds on your site. When you connect a page or group you will now see it listed in the "Connected Accounts" section. You can add it to the primary feed or to another feed by using the new `account` shortcode option.
261
+ * Tweak: Added a filter which can be used to filter the API data when returned; `cff_filter_api_data`.
262
+ * Tweak: Updated API error messages
263
+ * Fix: Fixed an issue with some @tag links in post text due to a Facebook API change
264
+ * Fix: Fixed a rare issue with ellipsis chracter symbols in shared link descriptions causing the entire link description not to be displayed
265
+
266
  = 2.11.1 =
267
  * Tweak: Added the link source URL below the title for shared link posts
268
  * Fix: Some themes would prevent the "Share" link from working successfully
css/cff-admin-style.css CHANGED
@@ -1060,13 +1060,15 @@
1060
  #cff-admin #cff-insert-token,
1061
  #cff-admin .cff-insert-reviews-token,
1062
  #cff-admin .cff-insert-both-tokens,
1063
- #cff-admin #cff-close-modal-primary-button{
 
1064
  margin-top: 25px;
1065
  float: left;
1066
  clear: both;
1067
  }
1068
  #cff-admin .cff-insert-reviews-token,
1069
- #cff-admin .cff-insert-both-tokens{
 
1070
  clear: none;
1071
  margin-left: 10px;
1072
  }
@@ -1300,4 +1302,375 @@
1300
  #cff-admin .cff-mobile-col-settings label {
1301
  font-weight: 600;
1302
  margin: 0 5px 0 0;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1303
  }
1060
  #cff-admin #cff-insert-token,
1061
  #cff-admin .cff-insert-reviews-token,
1062
  #cff-admin .cff-insert-both-tokens,
1063
+ #cff-admin #cff-close-modal-primary-button,
1064
+ #cff-admin #cff-insert-all-tokens{
1065
  margin-top: 25px;
1066
  float: left;
1067
  clear: both;
1068
  }
1069
  #cff-admin .cff-insert-reviews-token,
1070
+ #cff-admin .cff-insert-both-tokens,
1071
+ #cff-admin #cff-insert-all-tokens{
1072
  clear: none;
1073
  margin-left: 10px;
1074
  }
1302
  #cff-admin .cff-mobile-col-settings label {
1303
  font-weight: 600;
1304
  margin: 0 5px 0 0;
1305
+ }
1306
+
1307
+
1308
+ /* Connected Accounts */
1309
+ #cff-admin #cff_accounts_section{
1310
+ width: 100%;
1311
+ overflow: hidden;
1312
+ }
1313
+ #cff-admin #cff_connected_accounts_wrap{
1314
+ clear: both;
1315
+ max-height: 600px;
1316
+ overflow-y: auto;
1317
+ }
1318
+ #cff-admin #cff_accounts_section h3{
1319
+ float: left;
1320
+ clear: both;
1321
+ font-size: 14px;
1322
+ padding: 0;
1323
+ margin: 10px 0 5px 0;
1324
+ }
1325
+ #cff-admin .cff_connected_account {
1326
+ position: relative;
1327
+ box-sizing: border-box;
1328
+ padding: 7px 35px 7px 7px;
1329
+ border-radius: 5px;
1330
+ background: #fff;
1331
+ margin-bottom: 5px;
1332
+ overflow: hidden;
1333
+ clear: both;
1334
+ border: 1px solid #ddd;
1335
+ }
1336
+ #cff-admin .cff_ca_username {
1337
+ line-height: 1.4;
1338
+ margin-left: 15px;
1339
+ float: left;
1340
+ font-size: 18px;
1341
+ }
1342
+ #cff-admin .cff_connected_account .cff_ca_avatar{
1343
+ margin-right: 15px;
1344
+ }
1345
+ #cff-admin .cff_connected_account .cff_ca_username {
1346
+ margin-left: 0;
1347
+ margin-right: 25px;
1348
+ }
1349
+ #cff-admin .cff_connected_account .cff_ca_username strong{
1350
+ float: left;
1351
+ }
1352
+ #cff-admin .cff_connected_account .cff_ca_username .cff_ca_pagetype{
1353
+ font-size: 10px;
1354
+ font-weight: normal;
1355
+ text-transform: uppercase;
1356
+ padding: 0;
1357
+ margin: 0;
1358
+ display: block;
1359
+ }
1360
+
1361
+ #cff-admin .cff_ca_actions {
1362
+ display: inline-block;
1363
+ }
1364
+ #cff-admin .cff_ca_actions .fa{
1365
+ margin-right: 5px;
1366
+ }
1367
+ #cff-admin .cff_ca_actions a.button-primary,
1368
+ #cff-admin .cff_ca_actions a.button-secondary,
1369
+ #cff-admin .cff_ca_accesstoken a.cff_ca_token_shortcode {
1370
+ font-size: 12px;
1371
+ padding: 6px;
1372
+ height: auto;
1373
+ line-height: 1;
1374
+ margin: 7px 5px 0 0;
1375
+ vertical-align: top;
1376
+ }
1377
+ #cff-admin .cff_ca_at_is_valid {
1378
+ margin-top: 10px;
1379
+ display: none;
1380
+ }
1381
+ #cff-admin #cff_primary_account_label{
1382
+ padding: 0 0 0 1px;
1383
+ margin: 0;
1384
+ font-size: 12px;
1385
+ }
1386
+ #cff-admin #cff_primary_account_label span{
1387
+ padding: 0;
1388
+ margin: 0;
1389
+ display: inline-block;
1390
+ position: relative;
1391
+ top: -4px;
1392
+ }
1393
+ #cff-admin #cff_primary_account_label img{
1394
+ width: 18px;
1395
+ height: 18px;
1396
+ border-radius: 3px;
1397
+ padding: 0;
1398
+ margin: 0 5px 0 0;
1399
+ }
1400
+
1401
+ @-webkit-keyframes cff_flash {
1402
+ 0% {
1403
+ background-color: #cae2a5;
1404
+ opacity:1;
1405
+ border: 1px solid #b2ce88;
1406
+ }
1407
+ 100% {
1408
+ background-color: #fff;
1409
+ }
1410
+ }
1411
+ #cff-admin .cff_account_updated{
1412
+ border: 1px solid #ddd;
1413
+ background: #fff;
1414
+
1415
+ -webkit-animation-name: cff_flash;
1416
+ -webkit-animation-duration: 700ms;
1417
+ -webkit-animation-iteration-count: 1;
1418
+ -webkit-animation-timing-function: linear;
1419
+ -moz-animation-name: cff_flash;
1420
+ -moz-animation-duration: 700ms;
1421
+ -moz-animation-iteration-count: 1;
1422
+ -moz-animation-timing-function: linear;
1423
+ }
1424
+
1425
+ #cff-admin .cff_account_active{
1426
+ border: 1px solid #b2ce88;
1427
+ background: #ecf2e3;
1428
+ }
1429
+
1430
+ #cff-admin .cff_ca_alert {
1431
+ display: none;
1432
+ }
1433
+ #cff-admin .cff_account_invalid .cff_ca_alert {
1434
+ display: block;
1435
+ }
1436
+ #cff-admin .cff_ca_avatar{
1437
+ float: left;
1438
+ width: 40px;
1439
+ height: 40px;
1440
+ border-radius: 5px;
1441
+ }
1442
+ #cff-admin .cff_ca_accesstoken{
1443
+ display: none;
1444
+ width: 100%;
1445
+ float: left;
1446
+ clear: both;
1447
+ margin-top: 10px;
1448
+ }
1449
+ #cff-admin .cff_ca_token_label{
1450
+ display: inline-block;
1451
+ position: relative;
1452
+ background: #f9f9f9;
1453
+ color: #555;
1454
+ padding: 3px 5px;
1455
+ font-size: 12px;
1456
+ border: 1px solid #d6d6d6;
1457
+ height: 16px;
1458
+ line-height: 15px;
1459
+ border-radius: 4px 0 0 4px;
1460
+ }
1461
+ #cff-admin .cff_ca_token{
1462
+ position: relative;
1463
+ top: 1px;
1464
+ padding: 3px 10px;
1465
+ border: 1px solid #d6d6d6;
1466
+ border-left: none;
1467
+ font-size: 12px;
1468
+ border-radius: 0 4px 4px 0;
1469
+ background: rgba(255,255,255,0.8);
1470
+ width: 80%;
1471
+ display: inline-block;
1472
+ margin-left: 0;
1473
+ }
1474
+ #cff-admin a.cff_ca_token_shortcode,
1475
+ #cff-admin .cff_make_primary,
1476
+ #cff-admin .cff_ca_show_token a,
1477
+ #cff-admin .cff_make_reviews {
1478
+ padding: 4px 8px;
1479
+ display: inline-block;
1480
+ color: #555;
1481
+ border-radius: 3px;
1482
+ margin: 7px 0 0 0;
1483
+ font-size: 12px;
1484
+ text-decoration: none;
1485
+
1486
+ background: #fff;
1487
+ background: rgba(255,255,255,0.9);
1488
+ border: 1px solid #ccc;
1489
+ }
1490
+ #cff-admin .cff_make_primary,
1491
+ #cff-admin .cff_make_reviews{
1492
+ margin-right: 5px;
1493
+ background: #fff;
1494
+ background: rgba(255,255,255,0.9);
1495
+ border: 1px solid #ccc;
1496
+ }
1497
+ #cff-admin a.cff_ca_token_shortcode:hover,
1498
+ #cff-admin .cff_make_primary:hover,
1499
+ #cff-admin .cff_ca_show_token a:hover,
1500
+ #cff-admin .cff_make_reviews:hover{
1501
+ border: 1px solid #aaa;
1502
+ background: rgba(0,0,0,0.03);
1503
+ }
1504
+ #cff-admin a.cff_ca_token_shortcode:active,
1505
+ #cff-admin .cff_make_primary:active,
1506
+ #cff-admin .cff_ca_show_token a:active,
1507
+ #cff-admin .cff_make_reviews:active{
1508
+ background: rgba(255,255,255,0.9);
1509
+ border: 1px solid #ccc;
1510
+ }
1511
+
1512
+
1513
+ #cff-admin .cff_delete_account{
1514
+ position: absolute;
1515
+ right: 10px;
1516
+ top: 10px;
1517
+
1518
+ padding: 5px 10px;
1519
+ background: rgba(0,0,0,0.05);
1520
+ color: #666;
1521
+ border-radius: 50px;
1522
+ text-decoration: none;
1523
+ font-size: 12px;
1524
+ }
1525
+ #cff-admin .cff_delete_account:hover,
1526
+ #cff-admin .cff_delete_account:focus{
1527
+ background: #333;
1528
+ color: #ddd;
1529
+ }
1530
+ #cff-admin .cff_delete_account .cff_remove_text{
1531
+ display: none;
1532
+ margin-left: 5px;
1533
+ }
1534
+ #cff-admin .cff_delete_account:hover .cff_remove_text{
1535
+ display: inline-block;
1536
+ }
1537
+
1538
+ .cff_connected_accounts_wrap{
1539
+ vertical-align: top;
1540
+ }
1541
+ .cff_connected_actions{
1542
+ display: none;
1543
+ }
1544
+ #cff_export_accounts{
1545
+ font-size: 12px;
1546
+ color: #999 !important;
1547
+ text-decoration: underline;
1548
+ margin-left: 2px;
1549
+ }
1550
+ #cff_export_accounts_wrap{
1551
+ display: none;
1552
+ }
1553
+ #cff-admin .cff_no_accounts{
1554
+ display: inline-block;
1555
+ padding: 4px 15px;
1556
+ border-radius: 8px;
1557
+ background: rgba(255,255,255,0.8);
1558
+ margin-bottom: 3px;
1559
+ }
1560
+ #cff-admin #cff_manual_submit:active{
1561
+ vertical-align: unset;
1562
+ }
1563
+ #cff-admin .cff_manually_connect_wrap{
1564
+ padding-top: 5px;
1565
+ }
1566
+ #cff-admin .cff_user_feed_account_wrap:first-child{
1567
+ padding-top: 5px;
1568
+ }
1569
+ #cff-admin .cff_user_feed_account_wrap:last-child{
1570
+ padding-bottom: 6px;
1571
+ }
1572
+ #cff-admin .cff_user_feed_account_wrap{
1573
+ padding-bottom: 5px;
1574
+ padding-left: 2px;
1575
+ }
1576
+ #cff-admin .cff_user_feed_account_wrap span{
1577
+ font-size: 13px;
1578
+ }
1579
+ #cff-admin .cff_manual_account_id_toggle label{
1580
+ display: block;
1581
+ margin: 10px 0 0 0;
1582
+ font-size: 13px;
1583
+ }
1584
+ #cff-admin .cff_business_profile_tag{
1585
+ display: none;
1586
+ padding: 8px 10px;
1587
+ background: rgba(0,0,0,0.05);
1588
+ border-radius: 0 5px 5px 0;
1589
+ margin: 0 0 0 -2px;
1590
+ font-size: 13px;
1591
+ height: 15px;
1592
+ line-height: 15px;
1593
+ box-shadow: inset 0 0 1px rgba(0,0,0,.5);
1594
+ }
1595
+ #cff-admin .cff_ca_info{
1596
+ overflow: hidden;
1597
+ }
1598
+ #cff-admin .cff_ca_show_token{
1599
+ display: inline-block;
1600
+ padding: 0;
1601
+ margin: 0 0 0 5px;
1602
+ font-size: 12px;
1603
+ vertical-align: top;
1604
+ }
1605
+ #cff-admin .cff_ca_shortcode{
1606
+ display: none;
1607
+ padding: 0;
1608
+ width: 100%;
1609
+ float: left;
1610
+ clear: both;
1611
+ margin: 10px 0 0 0;
1612
+ }
1613
+ #cff-admin .cff_ca_shortcode p{
1614
+ margin: 0;
1615
+ padding: 15px 0 0 0;
1616
+ font-size: 13px;
1617
+ }
1618
+ #cff-admin .cff_ca_shortcode code{
1619
+ margin-top: 5px;
1620
+ display: inline-block;
1621
+ }
1622
+ #cff-admin .cff_user_feed_ids_wrap .cff_ca_avatar{
1623
+ width: 20px;
1624
+ height: 20px;
1625
+ position: relative;
1626
+ top: 5px;
1627
+ margin-right: 8px;
1628
+ border-radius: 4px;
1629
+ }
1630
+
1631
+ #cff-admin #cff_manual_account_step_2{
1632
+ display: none;
1633
+ }
1634
+ #cff-admin #cff_manual_account_button{
1635
+ float: left;
1636
+ clear: both;
1637
+ margin-bottom: 10px;
1638
+ }
1639
+ #cff-admin #cff_manual_account{
1640
+ float: left;
1641
+ clear: both;
1642
+ display: none;
1643
+ margin: 0 0 20px 0;
1644
+ padding: 15px 20px 20px 20px;
1645
+ background: rgba(255,255,255,0.5);
1646
+ border: 1px solid #ddd;
1647
+ border-radius: 5px;
1648
+ }
1649
+ #cff-admin #cff_manual_account p.submit{
1650
+ padding: 0;
1651
+ margin: 20px 0 0 0;
1652
+ }
1653
+ #cff-admin .cff_account_type_page .cff_group,
1654
+ #cff-admin .cff_account_type_group .cff_page{
1655
+ display: none;
1656
+ }
1657
+ #cff-admin #cff_manual_account_step_2 label {
1658
+ width: 165px;
1659
+ display: inline-block;
1660
+ }
1661
+ #cff-admin #cff_manual_account_step_2 input[type=text] {
1662
+ width: 300px;
1663
+ }
1664
+
1665
+ @media all and (max-width: 1200px){
1666
+ #cff-admin .cff_delete_account .cff_remove_text{
1667
+ display: none;
1668
+ }
1669
+ #cff-admin .cff_ca_token_label{
1670
+ display: none;
1671
+ }
1672
+ #cff-admin .cff_ca_token{
1673
+ border-left: 1px solid #d6d6d6;
1674
+ border-radius: 4px;
1675
+ }
1676
  }
css/cff-style.css CHANGED
@@ -490,8 +490,22 @@
490
 
491
  #cff .cff-error-msg{
492
  display: none;
 
493
  font-size: 12px;
494
  font-family: sans-serif;
 
 
 
 
 
 
 
 
 
 
 
 
 
495
  }
496
  #cff #cff-error-reason{
497
  display: none;
490
 
491
  #cff .cff-error-msg{
492
  display: none;
493
+ position: relative;
494
  font-size: 12px;
495
  font-family: sans-serif;
496
+ padding: 8px 12px;
497
+ border: 1px solid #ddd;
498
+ margin-bottom: 10px;
499
+ clear: both;
500
+
501
+ -webkit-border-radius: 3px;
502
+ -moz-border-radius: 3px;
503
+ -ms-border-radius: 3px;
504
+ -o-border-radius: 3px;
505
+ border-radius: 3px;
506
+ }
507
+ #cff .cff-error-msg p{
508
+ float: none;
509
  }
510
  #cff #cff-error-reason{
511
  display: none;
css/cff-style.min.css CHANGED
@@ -1 +1 @@
1
- .cff-wrapper:after{content:"";display:table;clear:both}#cff{float:left;width:100%;margin:0 auto;padding:0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}#cff .cff-item{float:left;width:100%;clear:both;padding:20px 0 15px 0;margin:0;border-bottom:1px solid #ddd}#cff .cff-item:first-child{padding-top:0}#cff .cff-item.cff-box,#cff .cff-item.cff-box:first-child{padding:15px;margin:8px 0;background:rgba(255,255,255,.5);border:none;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}#cff .cff-item.cff-box:first-child{margin-top:0}#cff .cff-item.cff-box:last-child{margin-bottom:0}#cff .cff-item.cff-shadow{box-shadow:0 0 10px 0 rgba(0,0,0,.15);-moz-box-shadow:0 0 10px 0 rgba(0,0,0,.15);-webkit-box-shadow:0 0 10px 0 rgba(0,0,0,.15)}.cff-header{width:100%;margin:0 0 15px 0;padding:0;line-height:1;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.cff-header .fa,.cff-header svg{margin:0 10px 0 0;padding:0}#cff .cff-less{display:none}#cff.cff-default-styles a{text-decoration:none}#cff.cff-default-styles a:focus,#cff.cff-default-styles a:hover{text-decoration:underline}#cff .cff-post-text-link{display:block}#cff .cff-post-desc,#cff h3,#cff h4,#cff h5,#cff h6,#cff p{float:left;width:100%;clear:both;padding:0;margin:5px 0;white-space:pre;white-space:pre-wrap;white-space:pre-line;white-space:-pre-wrap;white-space:-o-pre-wrap;white-space:-moz-pre-wrap;white-space:-hp-pre-wrap;word-wrap:break-word}#cff.cff-default-styles .cff-post-desc,#cff.cff-default-styles h3,#cff.cff-default-styles h4,#cff.cff-default-styles h5,#cff.cff-default-styles h6,#cff.cff-default-styles p{line-height:1.4}#cff .cff-date{float:left;min-width:50px;width:auto}#cff.cff-default-styles .cff-date{font-size:11px}#cff .cff-author{float:left;clear:both;margin:0 0 15px 0;padding:0;line-height:1.2;width:100%}#cff .cff-author a{text-decoration:none;border:none}#cff .cff-author-img{float:left;width:40px;height:40px;margin:0 0 0 -100%!important;font-size:0;background:#eee;background:url(../img/cff-avatar.png) no-repeat;border-radius:50%}#cff .cff-author img{float:left;margin:0!important;padding:0!important;border:none!important;font-size:0;border-radius:50%}#cff .cff-author .cff-author-text span.cff-page-name{display:table-cell;vertical-align:middle;height:40px;margin:0;font-weight:700;padding-left:50px;float:none}#cff .cff-author .cff-story{font-weight:400}#cff.cff-default-styles .cff-author a{text-decoration:none}#cff .cff-author.cff-no-author-info .cff-date{margin-top:12px!important}#cff .cff-author.cff-no-author-info .cff-author-img{width:40px;height:40px;background:url(../img/cff-avatar.png) no-repeat}#cff .cff-author .cff-author-text{float:left;width:100%}#cff .cff-author .cff-date,#cff .cff-author .cff-page-name{float:left;clear:both;width:auto;margin:0 0 0 50px!important}#cff.cff-default-styles .cff-author .cff-author-text *{font-weight:700;line-height:1.2}#cff .cff-author .cff-date{color:#9197a3;font-size:11px;margin-top:0!important;margin-bottom:0!important}#cff.cff-default-styles .cff-author .cff-date{font-weight:400}#cff .cff-author .cff-page-name.cff-author-date{float:left;padding:2px 0 0 0;font-size:14px}#cff .cff-cta-link a,.cff-media-link .fa{display:inline-block;width:auto;padding:5px 7px 5px 6px;margin-right:6px;border:1px solid #eee;border:1px solid rgba(0,0,0,.1);border-radius:3px;background:rgba(0,0,0,.02)}#cff .cff-cta-link a:hover,.cff-media-link .fa:hover{background:#f9f9f9;background:rgba(0,0,0,.03);text-decoration:none}#cff .cff-cta-link a{padding:5px 15px}#cff .cff-break-word{word-break:break-all}#cff .cff-expand{display:none}#cff.cff-default-styles .cff-expand a{font-size:11px;font-weight:400}#cff .cff-shared-link{float:left;clear:both;width:100%;padding:5px 10px;margin:10px 0 5px 0;background:#f9f9f9;border:1px solid #d9d9d9;background:rgba(0,0,0,.02);border:1px solid rgba(0,0,0,.07);-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}#cff .cff-no-styles{background:0 0;border:none;padding:0}#cff .cff-link{float:left;clear:both;max-width:20%;margin:10px 0 0 0}#cff .cff-link img{max-width:100%}#cff .cff-link-title{float:left;clear:both;width:100%;display:block}#cff.cff-default-styles .cff-link-title{font-weight:700}#cff p.cff-link-title{margin:5px 0 0 0}#cff .cff-text-link{float:left;clear:none;width:72%;margin-left:3%;padding:0 0 5px 0}#cff .cff-link-caption{margin:0}#cff.cff-default-styles .cff-link-caption{font-size:12px}#cff .cff-text-link.cff-no-image{width:100%;margin-left:0}#cff .cff-post-desc{margin:5px 0 0 0}#cff .cff-details{float:left;clear:none;width:100%;margin:0;padding:0}#cff .cff-details h5{margin:0 0 5px 0}#cff.cff-default-styles .cff-details h5{padding:0;font-size:16px}#cff.cff-default-styles .cff-details p{font-size:14px}#cff .cff-timeline-event .cff-date,#cff .cff-timeline-event .cff-info,#cff .cff-timeline-event .cff-timeline-event-title,#cff .cff-timeline-event .cff-where{display:block;width:100%;clear:both}#cff .cff-details .cff-info{padding:10px 0 0 0}#cff.cff-default-styles .cff-details .cff-info{line-height:1.2}#cff .cff-desc-wrap{float:left;width:100%}#cff .cff-note-title{display:block;font-weight:700;padding-bottom:5px}#cff .cff-post-links{float:left;clear:none;padding:5px 0 0 0;margin:0}#cff.cff-default-styles .cff-post-links{font-size:11px}#cff .cff-post-links.cff-left{float:left;margin:8px 0}#cff.cff-default-styles .cff-post-links a{font-size:11px}#cff .cff-post-links a:first-child{padding-left:0;margin:0}#cff .cff-dot{padding:0 5px}#cff .cff-share-container{position:relative;display:inline}#cff .cff-share-tooltip{display:none;position:absolute;z-index:1000;bottom:22px;right:-40px;width:110px;padding:5px 5px 4px 5px;margin:0;background:#333;color:#eee;font-size:12px;line-height:1.3;-moz-border-radius:4px;-webkit-border-radius:4px;border-radius:4px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}#cff .cff-share-tooltip .fa-play{position:absolute;font-size:8px;bottom:-6px;left:50%;margin-left:-3px;color:#333}#cff .cff-share-tooltip a .fa,#cff .cff-share-tooltip a svg{font-size:16px;margin:0;padding:5px}#cff .cff-share-tooltip a{display:block;float:left;margin:0!important;padding:0!important;color:#eee!important;opacity:0;-moz-border-radius:4px;-webkit-border-radius:4px;border-radius:4px}#cff .cff-share-tooltip a:hover{color:#fff!important}#cff .cff-share-tooltip .cff-facebook-icon:hover{background:#3b5998}#cff .cff-share-tooltip .cff-twitter-icon:hover{background:#00aced}#cff .cff-share-tooltip .cff-google-icon:hover{background:#dd4b39}#cff .cff-share-tooltip .cff-linkedin-icon:hover{background:#007bb6}#cff .cff-share-tooltip .cff-pinterest-icon:hover{background:#cb2027}#cff .cff-share-tooltip .cff-email-icon:hover{background:#dd4b39}#cff .cff-share-tooltip a.cff-show{opacity:1;transition:opacity .2s ease}.cff-likebox{float:left;width:100%;position:relative;margin:20px 0 0 0}.cff-likebox .fb_iframe_widget{width:100%}.cff-likebox .fb_iframe_widget span{width:100%!important}.cff-likebox .fb_iframe_widget iframe{margin:0;position:relative;top:0;left:0;width:100%!important;height:100%}.cff-likebox.cff-top.cff-outside{margin-bottom:10px}.cff-likebox.cff-bottom.cff-outside{margin-top:10px}#cff.cff-fixed-height{overflow:hidden;overflow-y:auto;padding:5px 10px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}#cff .cff-error-msg{display:none;font-size:12px;font-family:sans-serif}#cff #cff-error-reason{display:none;padding:5px 0 0 0;clear:both}#cff.cff-default-styles .cff-credit{font-size:11px}#cff.cff-default-styles .cff-credit a{text-decoration:none}#cff .cff-credit img{float:left;margin:-2px 5px 0 0}#cff .cff-credit .fa{padding-right:5px;font-size:13px}.cff-screenreader{text-indent:-9999px!important;display:block!important;width:0!important;height:0!important;line-height:0!important}@media all and (max-width:640px){#cff.cff-width-resp{width:100%!important}}#cff .cff-comment .cff-comment-text img,#cff img.emoji,#cff-lightbox-wrapper .cff-comment .cff-comment-text img,#cff-lightbox-wrapper img.emoji{float:none;max-width:100%}#cff .cff-linebreak{display:block;height:5px}#cff.cff-masonry .cff-item.cff-box{margin-left:1.5%;margin-right:1.5%}#cff.cff-masonry{box-sizing:border-box}#cff.cff-masonry .cff-item,#cff.cff-masonry .cff-item:first-child{padding-top:20px;margin-top:0}#cff.cff-masonry .cff-item,#cff.cff-masonry .cff-likebox{float:none;display:inline-block;width:30.3%;margin:0 1.5%;margin-bottom:20px}#cff.cff-masonry.cff-opaque-comments .cff-item{z-index:1}#cff.cff-masonry.masonry-2-desktop .cff-item{width:47%;margin:0 1.5%}#cff.cff-masonry.masonry-4-desktop .cff-item{width:22%;margin:0 1.5%}#cff.cff-masonry.masonry-5-desktop .cff-item{width:17%;margin:0 1.5%}#cff.cff-masonry.masonry-6-desktop .cff-item{width:13.516%;margin:0 1.5%}#cff.cff-masonry .cff-comments-box{position:relative;z-index:999}#cff.cff-masonry .cff-comment-attachment,#cff.cff-masonry .cff-comment-replies-box{max-width:100%}#cff.cff-masonry .cff-load-more{display:block;float:left;clear:both}@media (max-width:780px){#cff.cff-masonry .cff-item,#cff.cff-masonry .cff-likebox,#cff.cff-masonry.masonry-2-desktop .cff-item,#cff.cff-masonry.masonry-4-desktop .cff-item,#cff.cff-masonry.masonry-5-desktop .cff-item,#cff.cff-masonry.masonry-6-desktop .cff-item{width:100%;margin:0}#cff.cff-masonry.masonry-2-mobile .cff-item{width:47%;margin-left:1.5%;margin-right:1.5%}}#cff.cff-masonry.cff-masonry-css{width:100%;overflow:hidden;margin-bottom:20px}#cff.cff-masonry.cff-masonry-css{-webkit-column-gap:20px;-moz-column-gap:20px;column-gap:20px;-webkit-column-fill:auto;column-fill:unset;-webkit-column-count:3;-moz-column-count:3;column-count:3;margin:0}#cff.cff-masonry.cff-masonry-css.masonry-2-desktop{-webkit-column-count:2;-moz-column-count:2;column-count:2;margin:0}#cff.cff-masonry.cff-masonry-css.masonry-4-desktop{-webkit-column-count:4;-moz-column-count:4;column-count:4;margin:0}#cff.cff-masonry.cff-masonry-css.masonry-5-desktop{-webkit-column-count:5;-moz-column-count:5;column-count:5;margin:0}#cff.cff-masonry.cff-masonry-css.masonry-6-desktop{-webkit-column-count:6;-moz-column-count:6;column-count:6;margin:0}#cff.cff-masonry.cff-masonry-css .cff-item,#cff.cff-masonry.cff-masonry-css .cff-likebox,#cff.cff-masonry.cff-masonry-css.masonry-2-desktop .cff-item,#cff.cff-masonry.cff-masonry-css.masonry-4-desktop .cff-item,#cff.cff-masonry.cff-masonry-css.masonry-5-desktop .cff-item,#cff.cff-masonry.cff-masonry-css.masonry-6-desktop .cff-item{float:none;display:inline-block;width:100%;margin:0 0 12px 0}#cff.cff-masonry.cff-masonry-css .cff-likebox{width:99.5%}#cff.cff-masonry.cff-masonry-css .cff-load-more{margin:0 0 10px 0;position:relative;bottom:0}@media only screen and (max-width:780px){#cff.cff-masonry.cff-masonry-css,#cff.cff-masonry.cff-masonry-css.masonry-2-desktop,#cff.cff-masonry.cff-masonry-css.masonry-4-desktop,#cff.cff-masonry.cff-masonry-css.masonry-5-desktop,#cff.cff-masonry.cff-masonry-css.masonry-6-desktop{-webkit-column-count:1;-moz-column-count:1;column-count:1}#cff.cff-masonry.cff-masonry-css.masonry-2-mobile{-webkit-column-count:2;-moz-column-count:2;column-count:2;margin:0}#cff.cff-masonry.cff-masonry-css.masonry-2-mobile,#cff.cff-masonry.cff-masonry-css.masonry-2-mobile .cff-item{width:100%}}#cff.cff-disable-masonry{height:auto!important}#cff.cff-disable-masonry .cff-item,#cff.cff-disable-masonry .cff-likebox{position:relative!important;top:auto!important}
1
+ .cff-wrapper:after{content:"";display:table;clear:both}#cff{float:left;width:100%;margin:0 auto;padding:0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}#cff .cff-item{float:left;width:100%;clear:both;padding:20px 0 15px 0;margin:0;border-bottom:1px solid #ddd}#cff .cff-item:first-child{padding-top:0}#cff .cff-item.cff-box,#cff .cff-item.cff-box:first-child{padding:15px;margin:8px 0;background:rgba(255,255,255,.5);border:none;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}#cff .cff-item.cff-box:first-child{margin-top:0}#cff .cff-item.cff-box:last-child{margin-bottom:0}#cff .cff-item.cff-shadow{box-shadow:0 0 10px 0 rgba(0,0,0,.15);-moz-box-shadow:0 0 10px 0 rgba(0,0,0,.15);-webkit-box-shadow:0 0 10px 0 rgba(0,0,0,.15)}.cff-header{width:100%;margin:0 0 15px 0;padding:0;line-height:1;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.cff-header .fa,.cff-header svg{margin:0 10px 0 0;padding:0}#cff .cff-less{display:none}#cff.cff-default-styles a{text-decoration:none}#cff.cff-default-styles a:focus,#cff.cff-default-styles a:hover{text-decoration:underline}#cff .cff-post-text-link{display:block}#cff .cff-post-desc,#cff h3,#cff h4,#cff h5,#cff h6,#cff p{float:left;width:100%;clear:both;padding:0;margin:5px 0;white-space:pre;white-space:pre-wrap;white-space:pre-line;white-space:-pre-wrap;white-space:-o-pre-wrap;white-space:-moz-pre-wrap;white-space:-hp-pre-wrap;word-wrap:break-word}#cff.cff-default-styles .cff-post-desc,#cff.cff-default-styles h3,#cff.cff-default-styles h4,#cff.cff-default-styles h5,#cff.cff-default-styles h6,#cff.cff-default-styles p{line-height:1.4}#cff .cff-date{float:left;min-width:50px;width:auto}#cff.cff-default-styles .cff-date{font-size:11px}#cff .cff-author{float:left;clear:both;margin:0 0 15px 0;padding:0;line-height:1.2;width:100%}#cff .cff-author a{text-decoration:none;border:none}#cff .cff-author-img{float:left;width:40px;height:40px;margin:0 0 0 -100%!important;font-size:0;background:#eee;background:url(../img/cff-avatar.png) no-repeat;border-radius:50%}#cff .cff-author img{float:left;margin:0!important;padding:0!important;border:none!important;font-size:0;border-radius:50%}#cff .cff-author .cff-author-text span.cff-page-name{display:table-cell;vertical-align:middle;height:40px;margin:0;font-weight:700;padding-left:50px;float:none}#cff .cff-author .cff-story{font-weight:400}#cff.cff-default-styles .cff-author a{text-decoration:none}#cff .cff-author.cff-no-author-info .cff-date{margin-top:12px!important}#cff .cff-author.cff-no-author-info .cff-author-img{width:40px;height:40px;background:url(../img/cff-avatar.png) no-repeat}#cff .cff-author .cff-author-text{float:left;width:100%}#cff .cff-author .cff-date,#cff .cff-author .cff-page-name{float:left;clear:both;width:auto;margin:0 0 0 50px!important}#cff.cff-default-styles .cff-author .cff-author-text *{font-weight:700;line-height:1.2}#cff .cff-author .cff-date{color:#9197a3;font-size:11px;margin-top:0!important;margin-bottom:0!important}#cff.cff-default-styles .cff-author .cff-date{font-weight:400}#cff .cff-author .cff-page-name.cff-author-date{float:left;padding:2px 0 0 0;font-size:14px}#cff .cff-cta-link a,.cff-media-link .fa{display:inline-block;width:auto;padding:5px 7px 5px 6px;margin-right:6px;border:1px solid #eee;border:1px solid rgba(0,0,0,.1);border-radius:3px;background:rgba(0,0,0,.02)}#cff .cff-cta-link a:hover,.cff-media-link .fa:hover{background:#f9f9f9;background:rgba(0,0,0,.03);text-decoration:none}#cff .cff-cta-link a{padding:5px 15px}#cff .cff-break-word{word-break:break-all}#cff .cff-expand{display:none}#cff.cff-default-styles .cff-expand a{font-size:11px;font-weight:400}#cff .cff-shared-link{float:left;clear:both;width:100%;padding:5px 10px;margin:10px 0 5px 0;background:#f9f9f9;border:1px solid #d9d9d9;background:rgba(0,0,0,.02);border:1px solid rgba(0,0,0,.07);-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}#cff .cff-no-styles{background:0 0;border:none;padding:0}#cff .cff-link{float:left;clear:both;max-width:20%;margin:10px 0 0 0}#cff .cff-link img{max-width:100%}#cff .cff-link-title{float:left;clear:both;width:100%;display:block}#cff.cff-default-styles .cff-link-title{font-weight:700}#cff p.cff-link-title{margin:5px 0 0 0}#cff .cff-text-link{float:left;clear:none;width:72%;margin-left:3%;padding:0 0 5px 0}#cff .cff-link-caption{margin:0}#cff.cff-default-styles .cff-link-caption{font-size:12px}#cff .cff-text-link.cff-no-image{width:100%;margin-left:0}#cff .cff-post-desc{margin:5px 0 0 0}#cff .cff-details{float:left;clear:none;width:100%;margin:0;padding:0}#cff .cff-details h5{margin:0 0 5px 0}#cff.cff-default-styles .cff-details h5{padding:0;font-size:16px}#cff.cff-default-styles .cff-details p{font-size:14px}#cff .cff-timeline-event .cff-date,#cff .cff-timeline-event .cff-info,#cff .cff-timeline-event .cff-timeline-event-title,#cff .cff-timeline-event .cff-where{display:block;width:100%;clear:both}#cff .cff-details .cff-info{padding:10px 0 0 0}#cff.cff-default-styles .cff-details .cff-info{line-height:1.2}#cff .cff-desc-wrap{float:left;width:100%}#cff .cff-note-title{display:block;font-weight:700;padding-bottom:5px}#cff .cff-post-links{float:left;clear:none;padding:5px 0 0 0;margin:0}#cff.cff-default-styles .cff-post-links{font-size:11px}#cff .cff-post-links.cff-left{float:left;margin:8px 0}#cff.cff-default-styles .cff-post-links a{font-size:11px}#cff .cff-post-links a:first-child{padding-left:0;margin:0}#cff .cff-dot{padding:0 5px}#cff .cff-share-container{position:relative;display:inline}#cff .cff-share-tooltip{display:none;position:absolute;z-index:1000;bottom:22px;right:-40px;width:110px;padding:5px 5px 4px 5px;margin:0;background:#333;color:#eee;font-size:12px;line-height:1.3;-moz-border-radius:4px;-webkit-border-radius:4px;border-radius:4px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}#cff .cff-share-tooltip .fa-play{position:absolute;font-size:8px;bottom:-6px;left:50%;margin-left:-3px;color:#333}#cff .cff-share-tooltip a .fa,#cff .cff-share-tooltip a svg{font-size:16px;margin:0;padding:5px}#cff .cff-share-tooltip a{display:block;float:left;margin:0!important;padding:0!important;color:#eee!important;opacity:0;-moz-border-radius:4px;-webkit-border-radius:4px;border-radius:4px}#cff .cff-share-tooltip a:hover{color:#fff!important}#cff .cff-share-tooltip .cff-facebook-icon:hover{background:#3b5998}#cff .cff-share-tooltip .cff-twitter-icon:hover{background:#00aced}#cff .cff-share-tooltip .cff-google-icon:hover{background:#dd4b39}#cff .cff-share-tooltip .cff-linkedin-icon:hover{background:#007bb6}#cff .cff-share-tooltip .cff-pinterest-icon:hover{background:#cb2027}#cff .cff-share-tooltip .cff-email-icon:hover{background:#dd4b39}#cff .cff-share-tooltip a.cff-show{opacity:1;transition:opacity .2s ease}.cff-likebox{float:left;width:100%;position:relative;margin:20px 0 0 0}.cff-likebox .fb_iframe_widget{width:100%}.cff-likebox .fb_iframe_widget span{width:100%!important}.cff-likebox .fb_iframe_widget iframe{margin:0;position:relative;top:0;left:0;width:100%!important;height:100%}.cff-likebox.cff-top.cff-outside{margin-bottom:10px}.cff-likebox.cff-bottom.cff-outside{margin-top:10px}#cff.cff-fixed-height{overflow:hidden;overflow-y:auto;padding:5px 10px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}#cff .cff-error-msg{display:none;position:relative;font-size:12px;font-family:sans-serif;padding:8px 12px;border:1px solid #ddd;margin-bottom:10px;clear:both;-webkit-border-radius:3px;-moz-border-radius:3px;-ms-border-radius:3px;-o-border-radius:3px;border-radius:3px}#cff .cff-error-msg p{float:none}#cff #cff-error-reason{display:none;padding:5px 0 0 0;clear:both}#cff.cff-default-styles .cff-credit{font-size:11px}#cff.cff-default-styles .cff-credit a{text-decoration:none}#cff .cff-credit img{float:left;margin:-2px 5px 0 0}#cff .cff-credit .fa{padding-right:5px;font-size:13px}.cff-screenreader{text-indent:-9999px!important;display:block!important;width:0!important;height:0!important;line-height:0!important}@media all and (max-width:640px){#cff.cff-width-resp{width:100%!important}}#cff .cff-comment .cff-comment-text img,#cff img.emoji,#cff-lightbox-wrapper .cff-comment .cff-comment-text img,#cff-lightbox-wrapper img.emoji{float:none;max-width:100%}#cff .cff-linebreak{display:block;height:5px}#cff.cff-masonry .cff-item.cff-box{margin-left:1.5%;margin-right:1.5%}#cff.cff-masonry{box-sizing:border-box}#cff.cff-masonry .cff-item,#cff.cff-masonry .cff-item:first-child{padding-top:20px;margin-top:0}#cff.cff-masonry .cff-item,#cff.cff-masonry .cff-likebox{float:none;display:inline-block;width:30.3%;margin:0 1.5%;margin-bottom:20px}#cff.cff-masonry.cff-opaque-comments .cff-item{z-index:1}#cff.cff-masonry.masonry-2-desktop .cff-item{width:47%;margin:0 1.5%}#cff.cff-masonry.masonry-4-desktop .cff-item{width:22%;margin:0 1.5%}#cff.cff-masonry.masonry-5-desktop .cff-item{width:17%;margin:0 1.5%}#cff.cff-masonry.masonry-6-desktop .cff-item{width:13.516%;margin:0 1.5%}#cff.cff-masonry .cff-comments-box{position:relative;z-index:999}#cff.cff-masonry .cff-comment-attachment,#cff.cff-masonry .cff-comment-replies-box{max-width:100%}#cff.cff-masonry .cff-load-more{display:block;float:left;clear:both}@media (max-width:780px){#cff.cff-masonry .cff-item,#cff.cff-masonry .cff-likebox,#cff.cff-masonry.masonry-2-desktop .cff-item,#cff.cff-masonry.masonry-4-desktop .cff-item,#cff.cff-masonry.masonry-5-desktop .cff-item,#cff.cff-masonry.masonry-6-desktop .cff-item{width:100%;margin:0}#cff.cff-masonry.masonry-2-mobile .cff-item{width:47%;margin-left:1.5%;margin-right:1.5%}}#cff.cff-masonry.cff-masonry-css{width:100%;overflow:hidden;margin-bottom:20px}#cff.cff-masonry.cff-masonry-css{-webkit-column-gap:20px;-moz-column-gap:20px;column-gap:20px;-webkit-column-fill:auto;column-fill:unset;-webkit-column-count:3;-moz-column-count:3;column-count:3;margin:0}#cff.cff-masonry.cff-masonry-css.masonry-2-desktop{-webkit-column-count:2;-moz-column-count:2;column-count:2;margin:0}#cff.cff-masonry.cff-masonry-css.masonry-4-desktop{-webkit-column-count:4;-moz-column-count:4;column-count:4;margin:0}#cff.cff-masonry.cff-masonry-css.masonry-5-desktop{-webkit-column-count:5;-moz-column-count:5;column-count:5;margin:0}#cff.cff-masonry.cff-masonry-css.masonry-6-desktop{-webkit-column-count:6;-moz-column-count:6;column-count:6;margin:0}#cff.cff-masonry.cff-masonry-css .cff-item,#cff.cff-masonry.cff-masonry-css .cff-likebox,#cff.cff-masonry.cff-masonry-css.masonry-2-desktop .cff-item,#cff.cff-masonry.cff-masonry-css.masonry-4-desktop .cff-item,#cff.cff-masonry.cff-masonry-css.masonry-5-desktop .cff-item,#cff.cff-masonry.cff-masonry-css.masonry-6-desktop .cff-item{float:none;display:inline-block;width:100%;margin:0 0 12px 0}#cff.cff-masonry.cff-masonry-css .cff-likebox{width:99.5%}#cff.cff-masonry.cff-masonry-css .cff-load-more{margin:0 0 10px 0;position:relative;bottom:0}@media only screen and (max-width:780px){#cff.cff-masonry.cff-masonry-css,#cff.cff-masonry.cff-masonry-css.masonry-2-desktop,#cff.cff-masonry.cff-masonry-css.masonry-4-desktop,#cff.cff-masonry.cff-masonry-css.masonry-5-desktop,#cff.cff-masonry.cff-masonry-css.masonry-6-desktop{-webkit-column-count:1;-moz-column-count:1;column-count:1}#cff.cff-masonry.cff-masonry-css.masonry-2-mobile{-webkit-column-count:2;-moz-column-count:2;column-count:2;margin:0}#cff.cff-masonry.cff-masonry-css.masonry-2-mobile,#cff.cff-masonry.cff-masonry-css.masonry-2-mobile .cff-item{width:100%}}#cff.cff-disable-masonry{height:auto!important}#cff.cff-disable-masonry .cff-item,#cff.cff-disable-masonry .cff-likebox{position:relative!important;top:auto!important}
custom-facebook-feed-admin.php CHANGED
@@ -39,6 +39,7 @@ function cff_settings_page() {
39
  $show_access_token = 'cff_show_access_token';
40
  $access_token = 'cff_access_token';
41
  $page_id = 'cff_page_id';
 
42
  $cff_page_type = 'cff_page_type';
43
  $num_show = 'cff_num_show';
44
  $cff_post_limit = 'cff_post_limit';
@@ -50,6 +51,8 @@ function cff_settings_page() {
50
  $show_access_token_val = true;
51
  $access_token_val = get_option( $access_token );
52
  $page_id_val = get_option( $page_id );
 
 
53
  $cff_page_type_val = get_option( $cff_page_type, 'page' );
54
  $num_show_val = get_option( $num_show, '5' );
55
  $cff_post_limit_val = get_option( $cff_post_limit );
@@ -76,6 +79,7 @@ function cff_settings_page() {
76
  isset( $_POST[ $show_access_token ] ) ? $show_access_token_val = true : $show_access_token_val = true;
77
  isset( $_POST[ $access_token ] ) ? $access_token_val = sanitize_text_field( $_POST[ $access_token ] ) : $access_token_val = '';
78
  isset( $_POST[ $page_id ] ) ? $page_id_val = sanitize_text_field( $_POST[ $page_id ] ) : $page_id_val = '';
 
79
  isset( $_POST[ $cff_page_type ] ) ? $cff_page_type_val = sanitize_text_field( $_POST[ $cff_page_type ] ) : $cff_page_type_val = '';
80
  isset( $_POST[ $num_show ] ) ? $num_show_val = sanitize_text_field( $_POST[ $num_show ] ) : $num_show_val = '';
81
  isset( $_POST[ $cff_post_limit ] ) ? $cff_post_limit_val = sanitize_text_field( $_POST[ $cff_post_limit ] ) : $cff_post_limit_val = '';
@@ -89,6 +93,8 @@ function cff_settings_page() {
89
  update_option( $show_access_token, true );
90
  update_option( $access_token, $access_token_val );
91
  update_option( $page_id, $page_id_val );
 
 
92
  update_option( $cff_page_type, $cff_page_type_val );
93
  update_option( $num_show, $num_show_val );
94
  update_option( $cff_post_limit, $cff_post_limit_val );
@@ -265,7 +271,7 @@ function cff_settings_page() {
265
  foreach ( $groups_admin_data_arr->data as $page => $group_data ) {
266
  echo '<div class="cff-managed-page cff-group-admin';
267
  if( $group_data->id == $page_id_val ) echo ' cff-page-selected';
268
- echo '" data-token="'.$access_token.'" data-page-id="'.$group_data->id.'" id="cff_'.$group_data->id.'">';
269
  echo '<p>';
270
  if( isset( $group_data->picture->data->url ) ) echo '<img class="cff-page-avatar" border="0" height="50" width="50" src="'.$group_data->picture->data->url.'">';
271
  echo '<b class="cff-page-info-name">'.$group_data->name.'</b><span class="cff-page-info">(Group ID: '.$group_data->id.')</span></p>';
@@ -276,7 +282,7 @@ function cff_settings_page() {
276
  foreach ( $groups_data_arr->data as $page => $group_data ) {
277
  echo '<div class="cff-managed-page';
278
  if( $group_data->id == $page_id_val ) echo ' cff-page-selected';
279
- echo '" data-token="'.$access_token.'" data-page-id="'.$group_data->id.'" id="cff_'.$group_data->id.'">';
280
  echo '<p>';
281
  if( isset( $group_data->picture->data->url ) ) echo '<img class="cff-page-avatar" border="0" height="50" width="50" src="'.$group_data->picture->data->url.'">';
282
  echo '<b class="cff-page-info-name">'.$group_data->name.'</b><span class="cff-page-info">(Group ID: '.$group_data->id.')</span></p>';
@@ -323,14 +329,15 @@ function cff_settings_page() {
323
  foreach ( $pages_data_arr->data as $page => $page_data ) {
324
  echo '<div class="cff-managed-page ';
325
  if( $page_data->id == $page_id_val ) echo 'cff-page-selected';
326
- echo '" data-token="'.$page_data->access_token.'" data-page-id="'.$page_data->id.'">';
327
  echo '<p><img class="cff-page-avatar" border="0" height="50" width="50" src="https://graph.facebook.com/'.$page_data->id.'/picture"><b class="cff-page-info-name">'.$page_data->name.'</b><span class="cff-page-info">(Page ID: '.$page_data->id.')</span></p>';
328
  echo '</div>';
329
  }
330
  echo '</div>';
331
 
332
- $cff_use_token_text = 'Use token for this page';
333
  echo '<a href="JavaScript:void(0);" id="cff-insert-token" class="button button-primary" disabled="disabled">'.$cff_use_token_text.'</a>';
 
334
 
335
  }
336
 
@@ -355,7 +362,8 @@ function cff_settings_page() {
355
  <th scope="row"><label><?php _e('Facebook Page ID<br /><i style="font-weight: normal; font-size: 12px;">ID of your Facebook Page or Group</i>', 'custom-facebook-feed'); ?></label><code class="cff_shortcode"> id
356
  Eg: id="YOUR_PAGE_OR_GROUP_ID"</code></th>
357
  <td>
358
- <input name="cff_page_id" id="cff_page_id" type="text" value="<?php esc_attr_e( $page_id_val, 'custom-facebook-feed' ); ?>" size="45" />
 
359
  &nbsp;<a class="cff-tooltip-link" href="JavaScript:void(0);"><?php _e('What\'s my Page ID?', 'custom-facebook-feed'); ?></a>
360
  <br /><i style="color: #666; font-size: 11px;">Eg. 1234567890123 or smashballoon</i>
361
  <div class="cff-tooltip cff-more-info">
@@ -378,7 +386,7 @@ function cff_settings_page() {
378
  <tr valign="top">
379
  <th scope="row" style="padding-bottom: 10px;"><?php _e('Facebook Access Token', 'custom-facebook-feed'); ?><br /><i style="font-weight: normal; font-size: 12px; color: red;"><?php _e('Required', 'custom-facebook-feed'); ?></i></th>
380
  <td>
381
- <textarea name="cff_access_token" id="cff_access_token" style="min-width: 60%;"><?php esc_attr_e( $access_token_val ); ?></textarea><br /><a class="cff-tooltip-link" style="margin-left: 3px;" href="JavaScript:void(0);"><?php _e("What is this?", 'custom-facebook-feed'); ?></a>
382
  <p class="cff-tooltip cff-more-info"><?php _e("In order to connect to Facebook and get a feed, you need to use an Access Token. To get one, simply use the blue button above to log into your Facebook account. You will then receive a token that will be used to connect to Facebook's API. If you already have an Access Token then you can enter it here.", 'custom-facebook-feed'); ?></p>
383
 
384
  <div class="cff-notice cff-profile-error cff-access-token">
@@ -388,6 +396,64 @@ function cff_settings_page() {
388
  </tr>
389
  </tbody>
390
  </table>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
391
  <hr />
392
  <table class="form-table">
393
  <tbody>
@@ -763,7 +829,7 @@ foreach ( $plugins as $plugin_path => $plugin ) {
763
  ?>
764
 
765
  ## PLUGIN SETTINGS: ##
766
- Access Token: <?php echo chunk_split( get_option( 'cff_access_token' ), 100 ); ?>
767
  Page ID: <?php echo get_option( 'cff_page_id' ) ."\n"; ?>
768
  Number of Posts: <?php echo get_option( 'cff_num_show' ) ."\n"; ?>
769
  Post Limit: <?php echo get_option( 'cff_post_limit' ) ."\n"; ?>
39
  $show_access_token = 'cff_show_access_token';
40
  $access_token = 'cff_access_token';
41
  $page_id = 'cff_page_id';
42
+ $cff_connected_accounts = 'cff_connected_accounts';
43
  $cff_page_type = 'cff_page_type';
44
  $num_show = 'cff_num_show';
45
  $cff_post_limit = 'cff_post_limit';
51
  $show_access_token_val = true;
52
  $access_token_val = get_option( $access_token );
53
  $page_id_val = get_option( $page_id );
54
+ $cff_connected_accounts_val = get_option( $cff_connected_accounts );
55
+
56
  $cff_page_type_val = get_option( $cff_page_type, 'page' );
57
  $num_show_val = get_option( $num_show, '5' );
58
  $cff_post_limit_val = get_option( $cff_post_limit );
79
  isset( $_POST[ $show_access_token ] ) ? $show_access_token_val = true : $show_access_token_val = true;
80
  isset( $_POST[ $access_token ] ) ? $access_token_val = sanitize_text_field( $_POST[ $access_token ] ) : $access_token_val = '';
81
  isset( $_POST[ $page_id ] ) ? $page_id_val = sanitize_text_field( $_POST[ $page_id ] ) : $page_id_val = '';
82
+ isset( $_POST[ $cff_connected_accounts ] ) ? $cff_connected_accounts_val = $_POST[ $cff_connected_accounts ] : $cff_connected_accounts_val = '';
83
  isset( $_POST[ $cff_page_type ] ) ? $cff_page_type_val = sanitize_text_field( $_POST[ $cff_page_type ] ) : $cff_page_type_val = '';
84
  isset( $_POST[ $num_show ] ) ? $num_show_val = sanitize_text_field( $_POST[ $num_show ] ) : $num_show_val = '';
85
  isset( $_POST[ $cff_post_limit ] ) ? $cff_post_limit_val = sanitize_text_field( $_POST[ $cff_post_limit ] ) : $cff_post_limit_val = '';
93
  update_option( $show_access_token, true );
94
  update_option( $access_token, $access_token_val );
95
  update_option( $page_id, $page_id_val );
96
+ update_option( $cff_connected_accounts, $cff_connected_accounts_val );
97
+
98
  update_option( $cff_page_type, $cff_page_type_val );
99
  update_option( $num_show, $num_show_val );
100
  update_option( $cff_post_limit, $cff_post_limit_val );
271
  foreach ( $groups_admin_data_arr->data as $page => $group_data ) {
272
  echo '<div class="cff-managed-page cff-group-admin';
273
  if( $group_data->id == $page_id_val ) echo ' cff-page-selected';
274
+ echo '" data-token="'.$access_token.'" data-page-id="'.$group_data->id.'" id="cff_'.$group_data->id.'" data-pagetype="group">';
275
  echo '<p>';
276
  if( isset( $group_data->picture->data->url ) ) echo '<img class="cff-page-avatar" border="0" height="50" width="50" src="'.$group_data->picture->data->url.'">';
277
  echo '<b class="cff-page-info-name">'.$group_data->name.'</b><span class="cff-page-info">(Group ID: '.$group_data->id.')</span></p>';
282
  foreach ( $groups_data_arr->data as $page => $group_data ) {
283
  echo '<div class="cff-managed-page';
284
  if( $group_data->id == $page_id_val ) echo ' cff-page-selected';
285
+ echo '" data-token="'.$access_token.'" data-page-id="'.$group_data->id.'" id="cff_'.$group_data->id.'" data-pagetype="group">';
286
  echo '<p>';
287
  if( isset( $group_data->picture->data->url ) ) echo '<img class="cff-page-avatar" border="0" height="50" width="50" src="'.$group_data->picture->data->url.'">';
288
  echo '<b class="cff-page-info-name">'.$group_data->name.'</b><span class="cff-page-info">(Group ID: '.$group_data->id.')</span></p>';
329
  foreach ( $pages_data_arr->data as $page => $page_data ) {
330
  echo '<div class="cff-managed-page ';
331
  if( $page_data->id == $page_id_val ) echo 'cff-page-selected';
332
+ echo '" data-token="'.$page_data->access_token.'" data-page-id="'.$page_data->id.'" data-pagetype="page">';
333
  echo '<p><img class="cff-page-avatar" border="0" height="50" width="50" src="https://graph.facebook.com/'.$page_data->id.'/picture"><b class="cff-page-info-name">'.$page_data->name.'</b><span class="cff-page-info">(Page ID: '.$page_data->id.')</span></p>';
334
  echo '</div>';
335
  }
336
  echo '</div>';
337
 
338
+ $cff_use_token_text = 'Connect this page';
339
  echo '<a href="JavaScript:void(0);" id="cff-insert-token" class="button button-primary" disabled="disabled">'.$cff_use_token_text.'</a>';
340
+ echo '<a href="JavaScript:void(0);" id="cff-insert-all-tokens" class="button button-secondary cff_connect_all">Connect All</a>';
341
 
342
  }
343
 
362
  <th scope="row"><label><?php _e('Facebook Page ID<br /><i style="font-weight: normal; font-size: 12px;">ID of your Facebook Page or Group</i>', 'custom-facebook-feed'); ?></label><code class="cff_shortcode"> id
363
  Eg: id="YOUR_PAGE_OR_GROUP_ID"</code></th>
364
  <td>
365
+ <p id="cff_primary_account_label"></p>
366
+ <input name="cff_page_id" id="cff_page_id" type="text" value="<?php esc_attr_e( $page_id_val, 'custom-facebook-feed' ); ?>" size="45" data-page-id="<?php esc_attr_e( $page_id_val ); ?>" />
367
  &nbsp;<a class="cff-tooltip-link" href="JavaScript:void(0);"><?php _e('What\'s my Page ID?', 'custom-facebook-feed'); ?></a>
368
  <br /><i style="color: #666; font-size: 11px;">Eg. 1234567890123 or smashballoon</i>
369
  <div class="cff-tooltip cff-more-info">
386
  <tr valign="top">
387
  <th scope="row" style="padding-bottom: 10px;"><?php _e('Facebook Access Token', 'custom-facebook-feed'); ?><br /><i style="font-weight: normal; font-size: 12px; color: red;"><?php _e('Required', 'custom-facebook-feed'); ?></i></th>
388
  <td>
389
+ <textarea name="cff_access_token" id="cff_access_token" style="min-width: 60%;" data-accesstoken="<?php esc_attr_e( $access_token_val ); ?>"><?php esc_attr_e( $access_token_val ); ?></textarea><br /><a class="cff-tooltip-link" style="margin-left: 3px;" href="JavaScript:void(0);"><?php _e("What is this?", 'custom-facebook-feed'); ?></a>
390
  <p class="cff-tooltip cff-more-info"><?php _e("In order to connect to Facebook and get a feed, you need to use an Access Token. To get one, simply use the blue button above to log into your Facebook account. You will then receive a token that will be used to connect to Facebook's API. If you already have an Access Token then you can enter it here.", 'custom-facebook-feed'); ?></p>
391
 
392
  <div class="cff-notice cff-profile-error cff-access-token">
396
  </tr>
397
  </tbody>
398
  </table>
399
+
400
+ <div id="cff_accounts_section">
401
+ <a href="JavaScript:void(0);" class="button-secondary button" id="cff_manual_account_button">Manually connect account</a>
402
+
403
+ <div id="cff_manual_account">
404
+ <div id="cff_manual_account_step_1">
405
+ <label for="cff_manual_account_type"><?php _e('Is it a Facebook page or group?'); ?></label>
406
+ <select name="cff_manual_account_type" id="cff_manual_account_type">
407
+ <option value="" disabled selected><?php _e('- Select one -'); ?></option>
408
+ <option value="page"><?php _e('Page'); ?></option>
409
+ <option value="group"><?php _e('Group'); ?></option>
410
+ </select>
411
+ </div>
412
+
413
+ <div id="cff_manual_account_step_2" class="cff_account_type_page">
414
+ <div>
415
+ <label for="cff_manual_account_name"><span class="cff_page"><?php _e('Page'); ?></span><span class="cff_group"><?php _e('Group'); ?></span> <?php _e('Name'); ?> <span style="font-size: 11px;"><?php _e('(optional)'); ?></span></label>
416
+ <input name="cff_manual_account_name" id="cff_manual_account_name" type="text" value="" />
417
+ <a class="cff-tooltip-link" href="JavaScript:void(0);"><i class="fa fa-question-circle" aria-hidden="true"></i></a>
418
+ <p class="cff-tooltip cff-more-info"><?php _e('This is just for labeling the account here on this settings page'); ?></p>
419
+ </div>
420
+
421
+ <div>
422
+ <label for="cff_manual_account_id"><span class="cff_page"><?php _e('Page'); ?></span><span class="cff_group"><?php _e('Group'); ?></span> <?php _e('ID'); ?></label>
423
+ <input name="cff_manual_account_id" id="cff_manual_account_id" type="text" value="" />
424
+ <a class="cff-tooltip-link" href="JavaScript:void(0);"><i class="fa fa-question-circle" aria-hidden="true"></i></a>
425
+ <p class="cff-tooltip cff-more-info"><?php _e('The ID of the Facebook'); ?> <span class="cff_page"><?php _e('Page'); ?></span><span class="cff_group"><?php _e('Group'); ?></span> <?php _e('you want to add'); ?></p>
426
+ </div>
427
+
428
+ <div>
429
+ <label for="cff_manual_account_token"><?php _e('Access Token'); ?></label>
430
+ <input name="cff_manual_account_token" id="cff_manual_account_token" type="text" value="" />
431
+ <a class="cff-tooltip-link" href="JavaScript:void(0);"><i class="fa fa-question-circle" aria-hidden="true"></i></a>
432
+ <p class="cff-tooltip cff-more-info"><?php _e('The Access Token of the Facebook'); ?> <span class="cff_page"><?php _e('Page'); ?></span><span class="cff_group"><?php _e('Group'); ?></span> <?php _e('you want to add'); ?></p>
433
+ </div>
434
+
435
+ <?php
436
+ $cff_submit_btn_atts = array( 'disabled' => 'true' );
437
+ submit_button('Connect Account', 'primary', 'submit', true, $cff_submit_btn_atts);
438
+ ?>
439
+ </div>
440
+
441
+ </div>
442
+
443
+ <h3 class="cff_connected_actions">Connected Accounts:</h3>
444
+ <div id="cff_connected_accounts_wrap"><?php //Add connected accounts here ?></div>
445
+
446
+ <div class="cff_connected_actions">
447
+ <a href="JavaScript:void(0);" id="cff_export_accounts">Show raw account data</a>
448
+ <div id="cff_export_accounts_wrap">
449
+ <textarea name="cff_connected_accounts" id="cff_connected_accounts" style="width: 100%;" rows="5" /><?php echo stripslashes( esc_attr( $cff_connected_accounts_val ) ); ?></textarea>
450
+ </div>
451
+
452
+ <?php submit_button('Save Settings'); ?>
453
+ </div>
454
+
455
+ </div>
456
+
457
  <hr />
458
  <table class="form-table">
459
  <tbody>
829
  ?>
830
 
831
  ## PLUGIN SETTINGS: ##
832
+ Access Token: <?php echo chunk_split( get_option( 'cff_access_token' ), 110 ); ?>
833
  Page ID: <?php echo get_option( 'cff_page_id' ) ."\n"; ?>
834
  Number of Posts: <?php echo get_option( 'cff_num_show' ) ."\n"; ?>
835
  Post Limit: <?php echo get_option( 'cff_post_limit' ) ."\n"; ?>
custom-facebook-feed.php CHANGED
@@ -3,7 +3,7 @@
3
  Plugin Name: Smash Balloon Custom Facebook Feed
4
  Plugin URI: https://smashballoon.com/custom-facebook-feed
5
  Description: Add completely customizable Facebook feeds to your WordPress site
6
- Version: 2.11.1
7
  Author: Smash Balloon
8
  Author URI: http://smashballoon.com/
9
  License: GPLv2 or later
@@ -24,7 +24,7 @@ along with this program; if not, write to the Free Software
24
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25
  */
26
 
27
- define('CFFVER', '2.11.1');
28
 
29
  // Db version.
30
  if ( ! defined( 'CFF_DBVERSION' ) ) {
@@ -106,6 +106,7 @@ function display_cff($atts) {
106
  'locale' => get_option('cff_locale'),
107
  'ajax' => get_option('cff_ajax'),
108
  'offset' => '',
 
109
 
110
  //General
111
  'width' => isset($options[ 'cff_feed_width' ]) ? $options[ 'cff_feed_width' ] : '',
@@ -710,10 +711,32 @@ function display_cff($atts) {
710
  $title_limit = $atts['textlength'];
711
  if (!isset($title_limit)) $title_limit = 9999;
712
  $body_limit = $atts['desclength'];
 
713
  //Assign the Access Token and Page ID variables
714
  $access_token = $atts['accesstoken'];
715
  $page_id = trim( $atts['id'] );
716
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
717
  //If user pastes their full URL into the Page ID field then strip it out
718
  $cff_facebook_string = 'facebook.com';
719
  $cff_page_id_url_check = stripos($page_id, $cff_facebook_string);
@@ -725,8 +748,6 @@ function display_cff($atts) {
725
  $page_id = substr( $page_id, strrpos( $page_id, '/' )+1 );
726
  }
727
 
728
-
729
-
730
  //Masonry
731
  $masonry = false;
732
  $cff_cols = $atts['cols'];
@@ -759,8 +780,6 @@ function display_cff($atts) {
759
  }
760
  }
761
 
762
-
763
-
764
  //If the Page ID contains a query string at the end then remove it
765
  if ( stripos( $page_id, '?') !== false ) $page_id = substr($page_id, 0, strrpos($page_id, '?'));
766
 
@@ -992,19 +1011,42 @@ function display_cff($atts) {
992
 
993
  //Check whether any data is returned from the API. If it isn't then don't cache the error response and instead keep checking the API on every page load until data is returned.
994
  $FBdata = json_decode($posts_json);
995
- if( !empty($FBdata->data) ) {
996
 
997
- //If it's a rate limit error then don't cache the response so another token can be used
998
- if (strpos($posts_json, '"error":{"message":"(#4) Application request limit reached",') == false && strpos($posts_json, 'Error validating application. Application has been deleted.') == false) {
999
- //Cache the JSON
1000
- set_transient( $transient_name, $posts_json, $cache_seconds );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1001
  }
 
 
 
1002
 
1003
  }
1004
  } else {
 
1005
  $posts_json = get_transient( $transient_name );
1006
  //If we can't find the transient then fall back to just getting the json from the api
1007
  if ($posts_json == false) $posts_json = cff_fetchUrl($cff_posts_json_url);
 
1008
  }
1009
  } else {
1010
  $posts_json = cff_fetchUrl($cff_posts_json_url);
@@ -1015,33 +1057,40 @@ function display_cff($atts) {
1015
  $FBdata = json_decode($posts_json);
1016
 
1017
  //If there's no data then show a pretty error message
1018
- if( empty($FBdata->data) ) {
1019
- $cff_content .= '<div class="cff-error-msg"><p>Unable to display Facebook posts.<br/><a href="javascript:void(0);" id="cff-show-error" onclick="cffShowError()">Show error</a>';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1020
  $cff_content .= '<script type="text/javascript">function cffShowError() { document.getElementById("cff-error-reason").style.display = "block"; document.getElementById("cff-show-error").style.display = "none"; }</script>';
1021
  $cff_content .= '</p><div id="cff-error-reason">';
1022
 
1023
- if( isset($FBdata->error->message) ) $cff_content .= 'Error: ' . $FBdata->error->message;
1024
- if( isset($FBdata->error->type) ) $cff_content .= '<br />Type: ' . $FBdata->error->type;
1025
- if( isset($FBdata->error->code) ) $cff_content .= '<br />Code: ' . $FBdata->error->code;
1026
  if( isset($FBdata->error->error_subcode) ) $cff_content .= '<br />Subcode: ' . $FBdata->error->error_subcode;
1027
 
1028
- if( isset($FBdata->error_msg) ) $cff_content .= 'Error: ' . $FBdata->error_msg;
1029
  if( isset($FBdata->error_code) ) $cff_content .= '<br />Code: ' . $FBdata->error_code;
1030
 
1031
- if($FBdata == null) $cff_content .= 'Error: Server configuration issue';
1032
-
1033
- if( empty($FBdata->error) && empty($FBdata->error_msg) && $FBdata !== null ) $cff_content .= 'Error: No posts available for this Facebook ID';
1034
-
1035
- $cff_content .= '<br />Please refer to our <a href="https://smashballoon.com/custom-facebook-feed/docs/errors/" target="_blank">Error Message Reference</a>.';
1036
-
1037
  $cff_content .= '</div></div>'; //End .cff-error-msg and #cff-error-reason
1038
  //Only display errors to admins
1039
  if( current_user_can( 'manage_options' ) ){
1040
  $cff_content .= '<style>#cff .cff-error-msg{ display: block !important; }</style>';
1041
  }
1042
- $cff_content .= '</div></div>'; //End #cff and .cff-wrapper
1043
-
1044
- return $cff_content;
1045
  }
1046
 
1047
 
@@ -1055,923 +1104,931 @@ function display_cff($atts) {
1055
  }
1056
 
1057
  //***STARTS POSTS LOOP***
1058
- foreach ($FBdata->data as $news )
1059
- {
1060
- //Explode News and Page ID's into 2 values
1061
- $PostID = '';
1062
- $cff_post_id = '';
1063
- if( isset($news->id) ){
1064
- $cff_post_id = $news->id;
1065
- $PostID = explode("_", $cff_post_id);
1066
- }
1067
-
1068
- //Reassign variable changes from API v3.3 update
1069
- $news->link = '';
1070
- $news->description = '';
1071
- $news->name = '';
1072
- $news->caption = '';
1073
- $news->source = '';
1074
- $news->object_id = '';
1075
- if( isset($news->attachments->data[0]->unshimmed_url) ) $news->link = $news->attachments->data[0]->unshimmed_url;
1076
- if( isset($news->attachments->data[0]->description) ) $news->description = $news->attachments->data[0]->description;
1077
- if( isset($news->attachments->data[0]->target->id) ) $news->object_id = $news->attachments->data[0]->target->id;
1078
- if( isset($news->attachments->data[0]->media->source) ) $news->source = $news->attachments->data[0]->media->source;
1079
- if( isset($news->attachments->data[0]->title) ){
1080
- $news->name = $news->attachments->data[0]->title;
1081
- $news->caption = $news->attachments->data[0]->title;
1082
- }
1083
-
1084
- //Check the post type
1085
- $cff_post_type = 'status';
1086
- if( isset($news->attachments->data[0]->media_type) ) $cff_post_type = $news->attachments->data[0]->media_type;
1087
-
1088
- if ($cff_post_type == 'link') {
1089
- isset($news->story) ? $story = $news->story : $story = '';
1090
- //Check whether it's an event
1091
- $event_link_check = "facebook.com/events/";
1092
- if( isset($news->link) ){
1093
- $event_link_check = stripos($news->link, $event_link_check);
1094
- if ( $event_link_check ) $cff_post_type = 'event';
1095
  }
1096
- }
1097
-
1098
- //Should we show this post or not?
1099
- $cff_show_post = false;
1100
- switch ($cff_post_type) {
1101
- case 'link':
1102
- if ( $cff_show_links_type ) $cff_show_post = true;
1103
- break;
1104
- case 'event':
1105
- if ( $cff_show_event_type ) $cff_show_post = true;
1106
- break;
1107
- case 'video':
1108
- if ( $cff_show_video_type ) $cff_show_post = true;
1109
- break;
1110
- case 'swf':
1111
- if ( $cff_show_video_type ) $cff_show_post = true;
1112
- break;
1113
- case 'photo':
1114
- if ( $cff_show_photos_type ) $cff_show_post = true;
1115
- break;
1116
- case 'offer':
1117
- $cff_show_post = true;
1118
- break;
1119
- default:
1120
- //Check whether it's a status (author comment or like)
1121
- if ( $cff_show_status_type && !empty($news->message) ) $cff_show_post = true;
1122
- break;
1123
- }
1124
-
1125
- //Is it a duplicate post?
1126
- if (!isset($prev_post_message)) $prev_post_message = '';
1127
- if (!isset($prev_post_link)) $prev_post_link = '';
1128
- if (!isset($prev_post_description)) $prev_post_description = '';
1129
- isset($news->message) ? $pm = $news->message : $pm = '';
1130
- isset($news->link) ? $pl = $news->link : $pl = '';
1131
- isset($news->description) ? $pd = $news->description : $pd = '';
1132
-
1133
- if ( ($prev_post_message == $pm) && ($prev_post_link == $pl) && ($prev_post_description == $pd) ) $cff_show_post = false;
1134
 
1135
- //Offset. If the post index ($i_post) is less than the offset then don't show the post
1136
- if( intval($i_post) < intval($atts['offset']) ){
1137
- $cff_show_post = false;
1138
- $i_post++;
1139
- }
1140
-
1141
- //Check post type and display post if selected
1142
- if ( $cff_show_post ) {
1143
- //If it isn't then create the post
1144
- //Only create posts for the amount of posts specified
1145
- if( intval($atts['offset']) > 0 ){
1146
- //If offset is being used then stop after showing the number of posts + the offset
1147
- if ( $i_post == (intval($show_posts) + intval($atts['offset'])) ) break;
1148
- } else {
1149
- //Else just stop after the number of posts to be displayed is reached
1150
- if ( $i_post == $show_posts ) break;
1151
- }
1152
- $i_post++;
1153
- //********************************//
1154
- //***COMPILE SECTION VARIABLES***//
1155
- //********************************//
1156
- //Set the post link
1157
- isset($news->link) ? $link = htmlspecialchars($news->link) : $link = '';
1158
- //Is it a shared album?
1159
- $shared_album_string = 'shared an album:';
1160
- isset($news->story) ? $story = $news->story : $story = '';
1161
- $shared_album = stripos($story, $shared_album_string);
1162
- if ( $shared_album ) {
1163
- $link = str_replace('photo.php?','media/set/?',$link);
1164
  }
1165
 
1166
  //Check the post type
1167
- isset($cff_post_type) ? $cff_post_type = $cff_post_type : $cff_post_type = '';
 
 
1168
  if ($cff_post_type == 'link') {
1169
  isset($news->story) ? $story = $news->story : $story = '';
1170
  //Check whether it's an event
1171
  $event_link_check = "facebook.com/events/";
1172
- //Make sure URL doesn't include 'permalink' as that indicates someone else sharing a post from within an event (eg: https://www.facebook.com/events/617323338414282/permalink/617324268414189/) and the event ID is then not retrieved properly from the event URL as it's formatted like so: facebook.com/events/EVENT_ID/permalink/POST_ID
1173
- $event_link_check = stripos($news->link, $event_link_check);
1174
- $event_link_check_2 = stripos($news->link, "permalink/");
1175
- if ( $event_link_check && !$event_link_check_2 ) $cff_post_type = 'event';
1176
  }
1177
 
1178
- //If it's an event then check whether the URL contains facebook.com
1179
- if(isset($news->link)){
1180
- if( stripos($news->link, "events/") && $cff_post_type == 'event' ){
1181
- //Facebook changed the event link from absolute to relative, and so if the link isn't absolute then add facebook.com to front
1182
- ( stripos($link, 'facebook.com') ) ? $link = $link : $link = 'https://facebook.com' . $link;
1183
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1184
  }
1185
 
1186
- //Is it an album?
1187
- $cff_album = false;
1188
- if( isset($news->status_type) ){
1189
- if( $news->status_type == 'added_photos' ){
1190
- if( isset($news->attachments) ){
1191
- if( $news->attachments->data[0]->media_type == 'album' ) $cff_album = true;
1192
- }
1193
- }
 
 
 
 
 
 
1194
  }
1195
 
1196
- //If there's no link provided then link to either the Facebook page or the individual status
1197
- if (empty($news->link)) {
1198
- if ($cff_link_to_timeline == true){
1199
- //Link to page
1200
- $link = 'https://facebook.com/' . $page_id;
 
 
1201
  } else {
1202
- //Link to status
1203
- $link = "https://www.facebook.com/" . $page_id . "/posts/" . $PostID[1];
 
 
 
 
 
 
 
 
 
 
 
 
 
1204
  }
1205
- }
1206
 
1207
- //DATE
1208
- $cff_date_formatting = $atts[ 'dateformat' ];
1209
- $cff_date_custom = $atts[ 'datecustom' ];
 
 
 
 
 
 
 
 
1210
 
1211
- isset($news->created_time) ? $post_time = $news->created_time : $post_time = '';
1212
- if( isset($news->backdated_time) ) $post_time = $news->backdated_time; //If the post is backdated then use that as the date instead
 
 
 
 
 
1213
 
1214
- $cff_date = '<p class="cff-date" '.$cff_date_styles.'>'. $cff_date_before . ' ' . cff_getdate(strtotime($post_time), $cff_date_formatting, $cff_date_custom, $cff_date_translate_strings) . ' ' . $cff_date_after;
1215
- if($cff_date_position == 'below' || (!$cff_show_author && $cff_date_position == 'author') ) $cff_date .= '<span class="cff-date-dot">&nbsp;&middot;&nbsp;&nbsp;</span>';
1216
- $cff_date .= '</p>';
 
 
 
 
 
 
1217
 
1218
- //Page name
1219
- if( isset($news->from->name) ){
1220
- $cff_author_name = $news->from->name;
1221
- $cff_author_name = str_replace('"', "", $cff_author_name);
1222
- } else {
1223
- $cff_author_name = '';
1224
- }
 
 
 
1225
 
1226
- //Story/post text vars
1227
- $post_text = '';
1228
- $cff_post_text_type = '';
1229
- $cff_story_raw = '';
1230
- $cff_message_raw = '';
1231
- $cff_name_raw = '';
1232
- $text_tags = '';
1233
- $post_text_story = '';
1234
- $post_text_message = '';
1235
 
1236
- //STORY TAGS
1237
- $cff_post_tags = $atts[ 'posttags' ];
1238
 
1239
- //Use the story
1240
- if (!empty($news->story)) {
1241
- $cff_story_raw = $news->story;
1242
- $post_text_story .= htmlspecialchars($cff_story_raw);
1243
- $cff_post_text_type = 'story';
1244
 
 
 
 
 
 
 
 
1245
 
1246
- //Add message and story tags if there are any and the post text is the message or the story
1247
- if( $cff_post_tags && isset($news->story_tags) && !$cff_title_link){
1248
-
1249
- $text_tags = $news->story_tags;
 
 
 
 
 
1250
 
1251
- //Does the Post Text contain any html tags? - the & symbol is the best indicator of this
1252
- $cff_html_check_array = array('&lt;', '', '“', '&quot;', '&amp;', '&gt;&gt;');
1253
 
1254
- //always use the text replace method
1255
- if( cff_stripos_arr($post_text_story, $cff_html_check_array) !== false || ($cff_locale == 'el_GR' && count($news->story_tags) > 3) ) {
 
 
 
1256
 
1257
- //Loop through the tags
1258
- foreach($text_tags as $message_tag ) {
1259
 
1260
- ( isset($message_tag->id) ) ? $message_tag = $message_tag : $message_tag = $message_tag[0];
 
 
 
1261
 
1262
- $tag_name = $message_tag->name;
1263
- $tag_link = '<a href="https://facebook.com/' . $message_tag->id . '">' . $message_tag->name . '</a>';
1264
 
1265
- $post_text_story = str_replace($tag_name, $tag_link, $post_text_story);
1266
- }
1267
 
1268
- } else {
 
1269
 
1270
- //If it doesn't contain HTMl tags then use the offset to replace message tags
1271
- $message_tags_arr = array();
1272
-
1273
- $tag = 0;
1274
- foreach($text_tags as $message_tag ) {
1275
- $tag++;
1276
- ( isset($message_tag->id) ) ? $message_tag = $message_tag : $message_tag = $message_tag[0];
1277
-
1278
- isset($message_tag->type) ? $tag_type = $message_tag->type : $tag_type = '';
1279
-
1280
- $message_tags_arr = cff_array_push_assoc(
1281
- $message_tags_arr,
1282
- $tag,
1283
- array(
1284
- 'id' => $message_tag->id,
1285
- 'name' => $message_tag->name,
1286
- 'type' => isset($message_tag->type) ? $message_tag->type : '',
1287
- 'offset' => $message_tag->offset,
1288
- 'length' => $message_tag->length
1289
- )
1290
- );
1291
-
1292
- }
1293
 
1294
- //Keep track of the offsets so that if two tags have the same offset then only one is used. Need this as API 2.5 update changed the story_tag JSON format. A duplicate offset usually means '__ was with __ and 3 others'. We don't want to link the '3 others' part.
1295
- $cff_story_tag_offsets = '';
1296
- $cff_story_duplicate_offset = '';
1297
-
1298
- //Check if there are any duplicate offsets. If so, assign to the cff_story_duplicate_offset var.
1299
- for($tag = count($message_tags_arr); $tag >= 1; $tag--) {
1300
- $c = (string)$message_tags_arr[$tag]['offset'];
1301
- if( strpos( $cff_story_tag_offsets, $c ) !== false && $c !== '0' ){
1302
- $cff_story_duplicate_offset = $c;
1303
- } else {
1304
- $cff_story_tag_offsets .= $c . ',';
1305
  }
1306
-
1307
- }
1308
 
1309
- for($tag = count($message_tags_arr); $tag >= 1; $tag--) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1310
 
1311
- //If the name is blank (aka the story tag doesn't work properly) then don't use it
1312
- if( $message_tags_arr[$tag]['name'] !== '' ) {
 
1313
 
1314
- //If it's an event tag or it has the same offset as another tag then don't display it
1315
- if( $message_tags_arr[$tag]['type'] == 'event' || $message_tags_arr[$tag]['offset'] == $cff_story_duplicate_offset || $message_tags_arr[$tag]['type'] == 'page' ){
1316
- //Don't use the story tag in this case otherwise it changes '__ created an event' to '__ created an Name Of Event'
1317
- //Don't use the story tag if it's a page as it causes an issue when sharing a page: Smash Balloon Dev shared a Smash Balloon.
 
1318
  } else {
1319
- $b = '<a href="https://facebook.com/' . $message_tags_arr[$tag]['id'] . '" target="_blank">' . $message_tags_arr[$tag]['name'] . '</a>';
1320
- $c = $message_tags_arr[$tag]['offset'];
1321
- $d = $message_tags_arr[$tag]['length'];
1322
- $post_text_story = cff_mb_substr_replace( $post_text_story, $b, $c, $d);
1323
  }
1324
-
1325
  }
1326
 
1327
- }
1328
-
1329
- } // end if/else
1330
 
1331
- } //END STORY TAGS
 
1332
 
1333
- }
1334
-
1335
- //POST AUTHOR
1336
- $cff_author = '';
1337
- if( isset($news->from->id) ){
 
 
 
 
 
1338
 
1339
- $cff_author .= '<div class="cff-author">';
1340
 
1341
- //Check if the author from ID exists, as sometimes it doesn't
1342
- isset($news->from->id) ? $cff_from_id = $news->from->id : $cff_from_id = '';
1343
-
1344
- $cff_author_link_atts = 'href="https://facebook.com/' . $cff_from_id . '" '.$target.$cff_nofollow.' '.$cff_author_styles;
1345
 
1346
- //Link to the post if it's a visitor post as profile link no longer available
1347
- $cff_author_link_el = 'a';
1348
- $cff_author_link_atts = ' href="https://facebook.com/' . $cff_from_id . '" '.$target.$cff_nofollow.' '.$cff_author_styles;
1349
 
1350
- //If no link is available then change to span
1351
- if( !isset($news->from->link) ){
1352
- $cff_author_link_el = 'span';
1353
- $cff_author_link_atts = '';
1354
  }
 
 
 
 
1355
 
1356
- //Remove the first occurence of the author name from the story
1357
- if( !empty($cff_author_name) ){
1358
- $cff_author_name_pos = strpos($post_text_story, $cff_author_name);
1359
- if ($cff_author_name_pos !== false) {
1360
- $post_text_story = substr_replace($post_text_story, '', $cff_author_name_pos, strlen($cff_author_name));
 
 
 
 
 
 
 
 
 
 
1361
  }
1362
- }
1363
-
1364
- //Author text
1365
- $cff_author .= '<div class="cff-author-text">';
1366
- if($cff_show_date && $cff_date_position !== 'above' && $cff_date_position !== 'below'){
1367
- $cff_author .= '<p class="cff-page-name cff-author-date" '.$cff_author_styles.'><'.$cff_author_link_el.$cff_author_link_atts.'>'.$cff_author_name.'</'.$cff_author_link_el.'><span class="cff-story"> '.$post_text_story.'</span></p>';
1368
- $cff_author .= $cff_date;
1369
- } else {
1370
- $cff_author .= '<span class="cff-page-name"><'.$cff_author_link_el.$cff_author_link_atts.'>'.$cff_author_name.'</'.$cff_author_link_el.'><span class="cff-story"> '.$post_text_story.'</span></span>';
1371
- }
1372
 
1373
- $cff_author .= '</div>';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1374
 
1375
- //Author image
1376
- isset($news->from->picture->data->url) ? $cff_author_src = $news->from->picture->data->url : $cff_author_src = '';
1377
 
1378
- $cff_author .= '<div class="cff-author-img"><'.$cff_author_link_el.$cff_author_link_atts.'><img src="'.$cff_author_src.'" title="'.$cff_author_name.'" alt="'.$cff_author_name.'" width=40 height=40 onerror="this.style.display=\'none\'"></'.$cff_author_link_el.'></div>';
 
1379
 
1380
- $cff_author .= '</div>'; //End .cff-author
1381
 
1382
- } else {
1383
 
1384
- $cff_author .= '<div class="cff-author cff-no-author-info">';
1385
-
1386
- //Author text
1387
- $cff_author .= '<div class="cff-author-text">';
1388
- if($cff_show_date && $cff_date_position !== 'above' && $cff_date_position !== 'below'){
1389
- if( !empty($post_text_story) ) $cff_author .= '<p class="cff-page-name cff-author-date"><span class="cff-story"> '.$post_text_story.'</span></p>';
1390
- $cff_author .= $cff_date;
1391
  } else {
1392
- if( !empty($post_text_story) ) $cff_author .= '<span class="cff-page-name"><span class="cff-story"> '.$post_text_story.'</span></span>';
1393
- }
1394
- $cff_author .= '</div>';
1395
 
1396
- //Author image
1397
- $cff_author .= '<div class="cff-author-img"></div>';
1398
- $cff_author .= '</div>'; //End .cff-author
 
 
 
 
 
 
 
 
1399
 
1400
- }
 
 
1401
 
 
1402
 
1403
- //POST TEXT
1404
-
1405
- //Get the actual post text
1406
- //Which content should we use?
1407
- //Use the message
1408
- if (!empty($news->message)) {
1409
- $cff_message_raw = $news->message;
1410
-
1411
- $post_text_message = htmlspecialchars($cff_message_raw);
1412
- $cff_post_text_type = 'message';
1413
 
1414
- //MESSAGE TAGS
1415
- //Add message and story tags if there are any and the post text is the message or the story
1416
- if( $cff_post_tags && isset($news->message_tags) && !$cff_title_link){
 
 
 
 
1417
 
1418
- $text_tags = $news->message_tags;
1419
-
1420
- //Does the Post Text contain any html tags? - the & symbol is the best indicator of this
1421
- $cff_html_check_array = array('&lt;', '’', '“', '&quot;', '&amp;', '&gt;&gt;', '&gt;');
1422
 
1423
- //always use the text replace method
1424
- if( cff_stripos_arr($post_text_message, $cff_html_check_array) !== false ) {
1425
- //Loop through the tags
1426
- foreach($text_tags as $message_tag ) {
 
1427
 
1428
- ( isset($message_tag->id) ) ? $message_tag = $message_tag : $message_tag = $message_tag[0];
 
1429
 
1430
- $tag_name = $message_tag->name;
1431
- $tag_link = '<a href="https://facebook.com/' . $message_tag->id . '">' . $message_tag->name . '</a>';
 
 
1432
 
1433
- $post_text_message = str_replace($tag_name, $tag_link, $post_text_message);
1434
- }
1435
 
1436
- } else {
1437
- //If it doesn't contain HTMl tags then use the offset to replace message tags
1438
- $message_tags_arr = array();
1439
-
1440
- $tag = 0;
1441
- foreach($text_tags as $message_tag ) {
1442
- $tag++;
1443
-
1444
- ( isset($message_tag->id) ) ? $message_tag = $message_tag : $message_tag = $message_tag[0];
1445
-
1446
- $message_tags_arr = cff_array_push_assoc(
1447
- $message_tags_arr,
1448
- $tag,
1449
- array(
1450
- 'id' => $message_tag->id,
1451
- 'name' => $message_tag->name,
1452
- 'type' => isset($message_tag->type) ? $message_tag->type : '',
1453
- 'offset' => $message_tag->offset,
1454
- 'length' => $message_tag->length
1455
- )
1456
- );
1457
- }
1458
 
1459
- //Keep track of the offsets so that if two tags have the same offset then only one is used. Need this as API 2.5 update changed the story_tag JSON format.
1460
- $cff_msg_tag_offsets = '';
1461
- $cff_msg_duplicate_offset = '';
1462
-
1463
- //Check if there are any duplicate offsets. If so, assign to the cff_duplicate_offset var.
1464
- for($tag = count($message_tags_arr); $tag >= 1; $tag--) {
1465
- $c = (string)$message_tags_arr[$tag]['offset'];
1466
- if( strpos( $cff_msg_tag_offsets, $c ) !== false && $c !== '0' ){
1467
- $cff_msg_duplicate_offset = $c;
1468
- } else {
1469
- $cff_msg_tag_offsets .= $c . ',';
1470
  }
1471
- }
1472
 
1473
- for($tag = count($message_tags_arr); $tag >= 1; $tag--) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1474
 
1475
- //If the name is blank (aka the story tag doesn't work properly) then don't use it
1476
- if( $message_tags_arr[$tag]['name'] !== '' ) {
 
1477
 
1478
- if( $message_tags_arr[$tag]['offset'] == $cff_msg_duplicate_offset ){
1479
- //If it has the same offset as another tag then don't display it
 
 
 
1480
  } else {
1481
- $b = '<a href="https://facebook.com/' . $message_tags_arr[$tag]['id'] . '">' . $message_tags_arr[$tag]['name'] . '</a>';
1482
- $c = $message_tags_arr[$tag]['offset'];
1483
- $d = $message_tags_arr[$tag]['length'];
1484
- $post_text_message = cff_mb_substr_replace( $post_text_message, $b, $c, $d);
1485
  }
1486
-
1487
  }
1488
 
1489
- }
 
1490
 
1491
- } // end if/else
1492
 
1493
- } //END MESSAGE TAGS
 
1494
 
1495
- }
 
 
 
 
 
 
 
1496
 
 
 
 
 
 
 
 
1497
 
1498
- //Check to see whether it's an embedded video so that we can show the name above the post text if necessary
1499
- $cff_soundcloud = false;
1500
- $cff_is_video_embed = false;
1501
- if ($cff_post_type == 'video' || $cff_post_type == 'music'){
1502
- if( isset($news->source) && !empty($news->source) ){
1503
- $url = $news->source;
1504
- } else if ( isset($news->link) ) {
1505
- $url = $news->link;
1506
- } else {
1507
- $url = '';
1508
- }
1509
- //Embeddable video strings
1510
- $youtube = 'youtube';
1511
- $youtu = 'youtu';
1512
- $vimeo = 'vimeo';
1513
- $youtubeembed = 'youtube.com/embed';
1514
- $soundcloud = 'soundcloud.com';
1515
- $swf = '.swf';
1516
- //Check whether it's a youtube video
1517
- $youtube = stripos($url, $youtube);
1518
- $youtu = stripos($url, $youtu);
1519
- $youtubeembed = stripos($url, $youtubeembed);
1520
- //Check whether it's a SoundCloud embed
1521
-
1522
- $soundcloudembed = stripos($url, $soundcloud);
1523
- //Check whether it's a youtube video
1524
- if($youtube || $youtu || $youtubeembed || (stripos($url, $vimeo) !== false)) {
1525
- $cff_is_video_embed = true;
1526
  }
1527
- //If it's soundcloud then add it into the shared link box at the bottom of the post
1528
- if( $soundcloudembed ) $cff_soundcloud = true;
1529
 
1530
- $cff_video_name = '';
1531
- //If the name exists and it's a non-embedded video then show the name at the top of the post text
1532
- if( isset($news->name) && !$cff_is_video_embed ){
1533
 
1534
- if (!$cff_title_link) $cff_video_name .= '<a href="'.$link.'" '.$target.$cff_nofollow.' style="color: #'.$cff_posttext_link_color.'">';
1535
- $cff_video_name .= htmlspecialchars($news->name);
1536
- if (!$cff_title_link) $cff_video_name .= '</a>';
1537
- $cff_video_name .= '<br />';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1538
 
1539
- //Only show the video name if there's no post text
1540
- if( empty($post_text_message) || $post_text_message == '' || strlen($post_text_message) < 1 ){
1541
 
1542
- //If there's no description then show the video name above the post text, otherwise we'll show it below
1543
- if( empty($cff_description) || $cff_description == '' ) $post_text = $cff_video_name;
1544
 
 
1545
  }
1546
  }
1547
- }
1548
 
1549
- //Add the story and message together
1550
- $post_text = '';
1551
 
1552
- //DESCRIPTION
1553
- $cff_description = '';
1554
- if ( !empty($news->description) || !empty($news->caption) ) {
1555
- $description_text = '';
1556
 
1557
- if ( !empty($news->description) ) {
1558
- $description_text = $news->description;
1559
- }
1560
 
1561
- //If the description is the same as the post text then don't show it
1562
- if( $description_text == $cff_story_raw || $description_text == $cff_message_raw || $description_text == $cff_name_raw ){
1563
- $cff_description = '';
1564
- } else {
1565
- //Add links and create HTML
1566
- $cff_description .= '<span class="cff-post-desc" '.$cff_body_styles.'>';
1567
 
1568
- if ($cff_title_link) {
1569
- $cff_description_tagged = cff_wrap_span( htmlspecialchars($description_text) );
 
1570
  } else {
1571
- $cff_description_text = cff_autolink( htmlspecialchars($description_text), $link_color=$cff_posttext_link_color );
1572
- $cff_description_tagged = cff_desc_tags($cff_description_text);
 
 
 
 
 
 
 
 
 
 
1573
  }
1574
 
1575
- $cff_description .= $cff_description_tagged;
1576
- $cff_description .= ' </span>';
1577
  }
1578
-
1579
- if( $cff_post_type == 'event' || $cff_is_video_embed || $cff_soundcloud ) $cff_description = '';
1580
- }
1581
 
1582
- //Add the message
1583
- if($cff_show_text) $post_text .= $post_text_message;
1584
 
1585
- //If it's a shared video post then add the video name after the post text above the video description so it's all one chunk
1586
- if ($cff_post_type == 'video'){
1587
- if( !empty($cff_description) && $cff_description != '' ){
1588
- if( (!empty($post_text) && $post_text != '') && !empty($cff_video_name) ) $post_text .= '<br /><br />';
1589
- $post_text .= $cff_video_name;
 
1590
  }
1591
- }
1592
 
1593
 
1594
- //Use the name
1595
- if (!empty($news->name) && empty($news->message)) {
1596
- $cff_name_raw = $news->name;
1597
- $post_text = htmlspecialchars($cff_name_raw);
1598
- $cff_post_text_type = 'name';
1599
- }
1600
 
1601
- //OFFER TEXT
1602
- if ($cff_post_type == 'offer'){
1603
- isset($news->story) ? $post_text = htmlspecialchars($news->story) . '<br /><br />' : $post_text = '';
1604
- $post_text .= htmlspecialchars($news->name);
1605
- $cff_post_text_type = 'story';
1606
- }
1607
 
1608
- //Add the description
1609
- if( $cff_show_desc && $cff_post_type != 'offer' && $cff_post_type != 'link' ) $post_text .= $cff_description;
1610
 
1611
- //Change the linebreak element if the text issue setting is enabled
1612
- $cff_format_issue = $atts['textissue'];
1613
- ($cff_format_issue == 'true' || $cff_format_issue == 'on') ? $cff_format_issue = true : $cff_format_issue = false;
1614
- $cff_linebreak_el = '<br />';
1615
- if( $cff_format_issue ) $cff_linebreak_el = '<img class="cff-linebreak" />';
1616
 
1617
- //EVENT
1618
- $cff_event_has_cover_photo = false;
1619
- $cff_event = '';
1620
 
1621
 
1622
- //Create note
1623
- if ($cff_post_type == 'note') {
1624
-
1625
- // Get any existing copy of our transient data from previous versions
1626
- $transient_name = 'cff_tle_' . $cff_post_id;
1627
- $transient_name = substr($transient_name, 0, 45);
1628
- if ( false !== ( $cff_note_json = get_transient( $transient_name ) ) ) {
1629
- $cff_note_json = get_transient( $transient_name );
1630
-
1631
- //Interpret data with JSON
1632
- $cff_note_obj = json_decode($cff_note_json);
1633
- $cff_note_object = $cff_note_obj->attachments->data[0];
1634
- isset($cff_note_object->title) ? $cff_note_title = htmlentities($cff_note_object->title, ENT_QUOTES, 'UTF-8') : $cff_note_title = '';
1635
- isset($cff_note_object->description) ? $cff_note_description = htmlentities($cff_note_object->description, ENT_QUOTES, 'UTF-8') : $cff_note_description = '';
1636
- isset($cff_note_object->url) ? $cff_note_link = $cff_note_object->url : $cff_note_link = '';
1637
- isset( $cff_note_object->media->image->src ) ? $cff_note_media_src = $cff_note_object->media->image->src : $cff_note_media_src = false;
1638
- } else {
1639
- $attachment_data = '';
1640
- if(isset($news->attachments->data[0])){
1641
- $attachment_data = $news->attachments->data[0];
1642
- isset($attachment_data->title) ? $cff_note_title = htmlentities($attachment_data->title, ENT_QUOTES, 'UTF-8') : $cff_note_title = '';
1643
- isset($attachment_data->description) ? $cff_note_description = htmlentities($attachment_data->description, ENT_QUOTES, 'UTF-8') : $cff_note_description = '';
1644
- isset($attachment_data->unshimmed_url) ? $cff_note_link = $attachment_data->unshimmed_url : $cff_note_link = '';
1645
- $cff_note_media_src = '';
 
1646
  }
1647
- }
1648
 
1649
 
1650
- //Note details
1651
- $cff_note = '<span class="cff-details">';
1652
- $cff_note = '<span class="cff-note-title">'.$cff_note_title.'</span>';
1653
- $cff_note .= $cff_note_description;
1654
- $cff_note .= '</span>';
1655
 
1656
- //Notes don't include any post text and so just replace the post text with the note content
1657
- if($cff_show_text) $post_text = $cff_note;
1658
- }
1659
 
1660
 
1661
- //Create the HTML for the post text elemtent, if the post has text
1662
- $cff_post_text = '';
1663
 
1664
- if( !empty($post_text) ){
1665
- $cff_post_text = '<' . $cff_title_format . ' class="cff-post-text" ' . $cff_title_styles . '>';
1666
 
1667
- //Start HTML for post text
1668
- $cff_post_text .= '<span class="cff-text" data-color="'.$cff_posttext_link_color.'">';
1669
- if ($cff_title_link){
1670
- //Link to the Facebook post if it's a link or a video;
1671
- ($cff_post_type == 'link' || $cff_post_type == 'video') ? $text_link = "https://www.facebook.com/" . $page_id . "/posts/" . $PostID[1] : $text_link = $link;
1672
 
1673
- $cff_post_text .= '<a class="cff-post-text-link" '.$cff_title_styles.' href="'.$text_link.'" '.$target.$cff_nofollow.'>';
1674
- }
1675
-
1676
- //Replace line breaks in text (needed for IE8 and to prevent lost line breaks in HTML minification)
1677
- $post_text = preg_replace("/\r\n|\r|\n/",$cff_linebreak_el, $post_text);
1678
-
1679
- //If the text is wrapped in a link then don't hyperlink any text within
1680
- if ($cff_title_link) {
1681
- //Remove links from text
1682
- $result = preg_replace('/<a href=\"(.*?)\">(.*?)<\/a>/', "\\2", $post_text);
1683
- //Wrap links in a span so we can break the text if it's too long
1684
- $cff_post_text .= cff_wrap_span( $result ) . ' ';
1685
- } else {
1686
- //Don't use htmlspecialchars for post_text as it's added above so that it doesn't mess up the message_tag offsets
1687
- $cff_post_text .= cff_autolink( $post_text ) . ' ';
1688
- }
1689
-
1690
- if ($cff_title_link) $cff_post_text .= '</a>';
1691
- $cff_post_text .= '</span>';
1692
- //'See More' link
1693
- $cff_post_text .= '<span class="cff-expand">... <a href="#" style="color: #'.$cff_posttext_link_color.'"><span class="cff-more">' . $cff_see_more_text . '</span><span class="cff-less">' . $cff_see_less_text . '</span></a></span>';
1694
- $cff_post_text .= '</' . $cff_title_format . '>';
1695
-
1696
- //Facebook returns the text as "'s cover photo" for some reason, so ignore it
1697
- if( $post_text == "'s cover photo" ) $cff_post_text = '';
1698
- }
1699
 
1700
- //Add a call to action button if included
1701
- if( isset($news->call_to_action->value->link) ){
1702
- $cff_cta_link = $news->call_to_action->value->link;
1703
- //If it's not an absolute link then it means it's a relative Facebook one so prefix it with facebook.com
1704
- if (strpos($cff_cta_link, 'http') === false) $cff_cta_link = 'https://facebook.com' . $cff_cta_link;
1705
-
1706
- $cff_button_type = $news->call_to_action->type;
1707
-
1708
- switch ($cff_button_type) {
1709
- case 'SHOP_NOW':
1710
- $cff_translate_shop_now_text = $atts['shopnowtext'];
1711
- if (!isset($cff_translate_shop_now_text) || empty($cff_translate_shop_now_text)) $cff_translate_shop_now_text = 'Shop Now';
1712
- $cff_cta_button_text = $cff_translate_shop_now_text;
1713
- break;
1714
- case 'MESSAGE_PAGE':
1715
- $cff_translate_message_page_text = $atts['messagepage'];
1716
- if (!isset($cff_translate_message_page_text) || empty($cff_translate_message_page_text)) $cff_translate_message_page_text = 'Message Page';
1717
- $cff_cta_button_text = $cff_translate_message_page_text;
1718
- break;
1719
- case 'LEARN_MORE':
1720
- $cff_translate_learn_more_text = $atts['learnmoretext'];
1721
- if (!isset($cff_translate_learn_more_text) || empty($cff_translate_learn_more_text)) $cff_translate_learn_more_text = 'Learn More';
1722
- $cff_cta_button_text = $cff_translate_learn_more_text;
1723
- break;
1724
- default:
1725
- $cff_cta_button_text = ucwords(strtolower( str_replace('_',' ',$cff_button_type) ) );
1726
  }
1727
 
1728
- isset($news->call_to_action->value->app_link) ? $cff_app_link = $news->call_to_action->value->app_link : $cff_app_link = '';
1729
- $cff_post_text .= '<p class="cff-cta-link" '.$cff_title_styles.'><a href="'.$cff_cta_link.'" target="_blank" data-app-link="'.$cff_app_link.'" style="color: #'.$cff_posttext_link_color.';" >'.$cff_cta_button_text.'</a></p>';
1730
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1731
 
1732
- //LINK
1733
- $cff_shared_link = '';
1734
- //Display shared link
1735
- if ($cff_post_type == 'link' || $cff_soundcloud || $cff_is_video_embed) {
1736
-
1737
- $cff_shared_link .= '<div class="cff-shared-link';
1738
- if($cff_disable_link_box) $cff_shared_link .= ' cff-no-styles';
1739
-
1740
- $cff_shared_link .= '" ';
1741
-
1742
- if(!$cff_disable_link_box) $cff_shared_link .= $cff_link_box_styles;
1743
- $cff_shared_link .= '>';
1744
- $cff_link_image = '';
1745
-
1746
- //Display link name and description
1747
- $cff_shared_link .= '<div class="cff-text-link ';
1748
- if (!$cff_link_image) $cff_shared_link .= 'cff-no-image';
1749
- //The link title:
1750
- if( isset($news->name) ) $cff_shared_link .= '"><'.$cff_link_title_format.' class="cff-link-title" '.$cff_link_title_styles.'><a href="'.$link.'" '.$target.$cff_nofollow.' style="color:#' . $cff_link_title_color . ';">'. $news->name . '</a></'.$cff_link_title_format.'>';
1751
- //The link source:
1752
- if( !empty($news->link) ){
1753
- $cff_link_caption = htmlentities($news->link, ENT_QUOTES, 'UTF-8');
1754
- $cff_link_caption_parts = explode('/', $cff_link_caption);
1755
- if( isset($cff_link_caption_parts[2]) ) $cff_link_caption = $cff_link_caption_parts[2];
1756
- } else {
1757
- $cff_link_caption = '';
1758
  }
1759
 
1760
- //Shared link styles
1761
- $cff_link_url_color_html = '';
1762
- $cff_link_url_size_html = '';
1763
- if( isset($cff_link_url_color) && !empty($cff_link_url_color) && $cff_link_url_color != '#' ) $cff_link_url_color_html = 'color: #'.str_replace('#', '', $cff_link_url_color).';';
1764
- if( $cff_link_url_size != 'inherit' && !empty($cff_link_url_size) ) $cff_link_url_size_html = 'font-size:'.$cff_link_url_size.'px;';
1765
-
1766
- $cff_link_styles_html = '';
1767
- if( strlen($cff_link_url_color_html) > 1 || strlen($cff_link_url_size_html) > 1 ) $cff_link_styles_html = 'style="';
1768
- if( strlen($cff_link_url_color_html) > 1 ) $cff_link_styles_html .= $cff_link_url_color_html;
1769
- if( strlen($cff_link_url_size_html) > 1 ) $cff_link_styles_html .= $cff_link_url_size_html;
1770
- if( strlen($cff_link_url_color_html) > 1 || strlen($cff_link_url_size_html) > 1 ) $cff_link_styles_html .= '"';
1771
-
1772
- if(!empty($cff_link_caption)) $cff_shared_link .= '<p class="cff-link-caption" '.$cff_link_styles_html.'>'.$cff_link_caption.'</p>';
1773
- if ($cff_show_desc) {
1774
- //Truncate desc
1775
- if (!empty($body_limit)) {
1776
- if (strlen($description_text) > $body_limit) $description_text = substr($description_text, 0, $body_limit) . '...';
 
 
 
 
 
 
 
 
 
1777
  }
1778
 
1779
- //Shared link desc styles
1780
- $cff_link_desc_color_html = '';
1781
- $cff_link_desc_size_html = '';
1782
- if( isset($cff_link_desc_color) && !empty($cff_link_desc_color) && $cff_link_desc_color != '#' ) $cff_link_desc_color_html = 'color: #'.str_replace('#', '', $cff_link_desc_color).';';
1783
- if( $cff_link_desc_size != 'inherit' && !empty($cff_link_desc_size) ) $cff_link_desc_size_html = 'font-size:'.$cff_link_desc_size.'px;';
 
 
 
 
 
 
 
 
 
 
 
 
 
1784
 
1785
- $cff_link_desc_styles_html = '';
1786
- if( strlen($cff_link_desc_color_html) > 1 || strlen($cff_link_desc_size_html) > 1 ) $cff_link_desc_styles_html = 'style="';
1787
- if( strlen($cff_link_desc_color_html) > 1 ) $cff_link_desc_styles_html .= $cff_link_desc_color_html;
1788
- if( strlen($cff_link_desc_size_html) > 1 ) $cff_link_desc_styles_html .= $cff_link_desc_size_html;
1789
- if( strlen($cff_link_desc_color_html) > 1 || strlen($cff_link_desc_size_html) > 1 ) $cff_link_desc_styles_html .= '"';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1790
 
1791
- //Add links and create HTML
1792
- $cff_link_description = '<span class="cff-post-desc" '.$cff_link_desc_styles_html.'>';
1793
- if ($cff_title_link) {
1794
- $cff_link_description .= cff_wrap_span( htmlspecialchars($description_text) );
1795
- } else {
1796
- $description_text = cff_autolink( htmlspecialchars($description_text), $link_color=$cff_posttext_link_color );
1797
- //Replace line breaks with <br> tags
1798
- $cff_link_description .= nl2br($description_text);
1799
- }
1800
- $cff_link_description .= ' </span>';
1801
 
 
 
1802
 
1803
- if( $description_text != $cff_link_caption ) $cff_shared_link .= $cff_link_description;
1804
  }
1805
 
1806
- $cff_shared_link .= '</div></div>';
1807
- }
1808
 
1809
- /* VIDEO */
1810
-
1811
- //Check to see whether it's an embedded video so that we can show the name above the post text if necessary
1812
- $cff_is_video_embed = false;
1813
- if ( $cff_post_type == 'video' && isset($news->source) ){
1814
- $url = $news->source;
1815
- //Embeddable video strings
1816
- $youtube = 'youtube';
1817
- $youtu = 'youtu';
1818
- $vimeo = 'vimeo';
1819
- $youtubeembed = 'youtube.com/embed';
1820
- //Check whether it's a youtube video
1821
- $youtube = stripos($url, $youtube);
1822
- $youtu = stripos($url, $youtu);
1823
- $youtubeembed = stripos($url, $youtubeembed);
1824
- //Check whether it's a youtube video
1825
- if($youtube || $youtu || $youtubeembed || (stripos($url, $vimeo) !== false)) {
1826
- $cff_is_video_embed = true;
1827
  }
1828
- }
1829
 
1830
 
1831
- $cff_media = '';
1832
- if ($cff_post_type == 'video') {
1833
- //Add the name to the description if it's a video embed
1834
- if($cff_is_video_embed) {
1835
- isset($news->name) ? $video_name = $news->name : $video_name = $link;
1836
- isset($news->description) ? $description_text = $news->description : $description_text = '';
1837
- //Add the 'cff-shared-link' class so that embedded videos display in a box
1838
- $cff_description = '<div class="cff-desc-wrap cff-shared-link ';
1839
- if (empty($picture)) $cff_description .= 'cff-no-image';
1840
- if($cff_disable_link_box) $cff_description .= ' cff-no-styles"';
1841
- if(!$cff_disable_link_box) $cff_description .= '" ' . $cff_link_box_styles;
1842
- $cff_description .= '>';
1843
 
1844
- if( isset($news->name) ) $cff_description .= '<'.$cff_link_title_format.' class="cff-link-title" '.$cff_link_title_styles.'><a href="'.$link.'" '.$target.$cff_nofollow.' style="color:#' . $cff_link_title_color . ';">'. $news->name . '</a></'.$cff_link_title_format.'>';
1845
 
1846
- if (!empty($body_limit)) {
1847
- if (strlen($description_text) > $body_limit) $description_text = substr($description_text, 0, $body_limit) . '...';
1848
- }
1849
 
1850
- $cff_description .= '<p class="cff-post-desc" '.$cff_body_styles.'><span>' . cff_autolink( htmlspecialchars($description_text) ) . '</span></p></div>';
1851
- } else {
1852
- isset($news->name) ? $video_name = $news->name : $video_name = $link;
1853
- if( isset($news->name) ) $cff_description .= '<'.$cff_link_title_format.' class="cff-link-title" '.$cff_link_title_styles.'><a href="'.$link.'" '.$target.$cff_nofollow.' style="color:#' . $cff_link_title_color . ';">'. $news->name . '</a></'.$cff_link_title_format.'>';
 
1854
  }
1855
- }
1856
 
1857
 
1858
- //Display the link to the Facebook post or external link
1859
- $cff_link = '';
1860
- //Default link
1861
- $cff_viewpost_class = 'cff-viewpost-facebook';
1862
- if ($cff_facebook_link_text == '') $cff_facebook_link_text = 'View on Facebook';
1863
- $link_text = $cff_facebook_link_text;
1864
 
1865
- //Link to the Facebook post if it's a link or a video
1866
- if($cff_post_type == 'link' || $cff_post_type == 'video') $link = "https://www.facebook.com/" . $page_id . "/posts/" . $PostID[1];
1867
 
1868
- //Social media sharing URLs
1869
- $cff_share_facebook = 'https://www.facebook.com/sharer/sharer.php?u=' . urlencode($link);
1870
- $cff_share_twitter = 'https://twitter.com/intent/tweet?text=' . urlencode($link);
1871
- $cff_share_google = 'https://plus.google.com/share?url=' . urlencode($link);
1872
- $cff_share_linkedin = 'https://www.linkedin.com/shareArticle?mini=true&amp;url=' . urlencode($link) . '&amp;title=' . rawurlencode( strip_tags($cff_post_text) );
1873
- $cff_share_email = 'mailto:?subject=Facebook&amp;body=' . urlencode($link) . '%20-%20' . rawurlencode( strip_tags($cff_post_text) );
1874
 
1875
- //If it's a shared post then change the link to use the Post ID so that it links to the shared post and not the original post that's being shared
1876
- if( isset($news->status_type) ){
1877
- if( $news->status_type == 'shared_story' ) $link = "https://www.facebook.com/" . $cff_post_id;
1878
- }
1879
 
1880
- //If it's an offer post then change the text
1881
- if ($cff_post_type == 'offer') $link_text = 'View Offer';
1882
 
1883
- //Create post action links HTML
1884
- $cff_link = '';
1885
- if($cff_show_facebook_link || $cff_show_facebook_share){
1886
- $cff_link .= '<div class="cff-post-links">';
1887
 
1888
- //View on Facebook link
1889
- if($cff_show_facebook_link) $cff_link .= '<a class="' . $cff_viewpost_class . '" href="' . $link . '" title="' . $link_text . '" ' . $target . $cff_nofollow . ' ' . $cff_link_styles . '>' . $link_text . '</a>';
1890
 
1891
- //Share link
1892
- if($cff_show_facebook_share){
1893
- $cff_link .= '<div class="cff-share-container">';
1894
- //Only show separating dot if both links are enabled
1895
- if($cff_show_facebook_link) $cff_link .= '<span class="cff-dot" ' . $cff_link_styles . '>&middot;</span>';
1896
- $cff_link .= '<a class="cff-share-link" href="'.$cff_share_facebook.'" title="' . $cff_facebook_share_text . '" ' . $cff_link_styles . '>' . $cff_facebook_share_text . '</a>';
1897
- $cff_link .= "<p class='cff-share-tooltip'><a href='".$cff_share_facebook."' target='_blank' class='cff-facebook-icon'><span class='fa fab fa-facebook-square' aria-hidden='true'></span><span class='cff-screenreader'>Share on Facebook</span></a><a href='".$cff_share_twitter."' target='_blank' class='cff-twitter-icon'><span class='fa fab fa-twitter' aria-hidden='true'></span><span class='cff-screenreader'>Share on Twitter</span></a><a href='".$cff_share_linkedin."' target='_blank' class='cff-linkedin-icon'><span class='fa fab fa-linkedin' aria-hidden='true'></span><span class='cff-screenreader'>Share on Linked In</span></a><a href='".$cff_share_email."' target='_blank' class='cff-email-icon'><span class='fa fa-envelope' aria-hidden='true'></span><span class='cff-screenreader'>Share by Email</span></a><span class='fa fa-play fa-rotate-90' aria-hidden='true'></span></p></div>";
 
 
 
1898
  }
1899
-
1900
- $cff_link .= '</div>';
1901
- }
1902
 
1903
 
1904
- /* MEDIA LINK */
1905
- $cff_translate_photo_text = $atts['phototext'];
1906
- if (!isset($cff_translate_photo_text) || empty($cff_translate_photo_text)) $cff_translate_photo_text = 'Photo';
1907
- $cff_translate_video_text = $atts['videotext'];
1908
- if (!isset($cff_translate_video_text) || empty($cff_translate_video_text)) $cff_translate_video_text = 'Video';
1909
 
1910
- $cff_media_link = '';
1911
 
1912
- if( $cff_show_media_link && ($cff_post_type == 'photo' || $cff_post_type == 'video' || $cff_album) ){
1913
- $cff_media_link .= '<p class="cff-media-link"><a href="'.$link.'" '.$target.' style="color: #'.$cff_posttext_link_color.';"><span style="padding-right: 5px;" class="fa fas fa-';
1914
- if($cff_post_type == 'photo' || $cff_album) $cff_media_link .= 'picture-o fa-image" aria-hidden="true"></span>'. $cff_translate_photo_text;
1915
- // if($cff_post_type == 'video') $cff_media_link .= 'file-video-o';
1916
- if($cff_post_type == 'video') $cff_media_link .= 'video-camera fa-video" aria-hidden="true"></span>'. $cff_translate_video_text;
1917
- $cff_media_link .= '</a></p>';
1918
- }
1919
-
1920
- //**************************//
1921
- //***CREATE THE POST HTML***//
1922
- //**************************//
1923
- //Start the container
1924
- $cff_post_item = '<div class="cff-item ';
1925
- $cff_post_type_class = 'cff-status-post';
1926
- if ($cff_post_type == 'link') $cff_post_type_class = 'cff-link-item';
1927
- if ($cff_post_type == 'event') $cff_post_type_class = 'cff-timeline-event';
1928
- if ($cff_post_type == 'photo') $cff_post_type_class = 'cff-photo-post';
1929
- if ($cff_post_type == 'video') $cff_post_type_class = 'cff-video-post';
1930
- if ($cff_post_type == 'swf') $cff_post_type_class = 'cff-swf-post';
1931
- if ($cff_post_type == 'offer') $cff_post_type_class = 'cff-offer-post';
1932
- $cff_post_item .= $cff_post_type_class;
1933
- if ($cff_album) $cff_post_item .= ' cff-album';
1934
-
1935
- if ($cff_post_bg_color_check || $cff_post_style == "boxed") $cff_post_item .= ' cff-box';
1936
- if( $cff_box_shadow ) $cff_post_item .= ' cff-shadow';
1937
- if(isset($news->from->name)) $cff_post_item .= ' author-'. cff_to_slug($news->from->name);
1938
- $cff_post_item .= '" id="cff_'. $cff_post_id .'" ' . $cff_item_styles . '>';
1939
-
1940
- //POST AUTHOR
1941
- if($cff_show_author) $cff_post_item .= $cff_author;
1942
- //DATE ABOVE
1943
- if ($cff_show_date && $cff_date_position == 'above') $cff_post_item .= $cff_date;
1944
- //POST TEXT
1945
- if($cff_show_text || $cff_show_desc) $cff_post_item .= $cff_post_text;
1946
- //LINK
1947
- if($cff_show_shared_links) $cff_post_item .= $cff_shared_link;
1948
- //DATE BELOW
1949
- if ( (!$cff_show_author && $cff_date_position == 'author') || $cff_show_date && $cff_date_position == 'below') {
1950
- if($cff_show_date && $cff_post_type !== 'event') $cff_post_item .= $cff_date;
1951
- }
1952
- //DATE BELOW (only for Event posts)
1953
- if ( (!$cff_show_author && $cff_date_position == 'author') || $cff_show_date && $cff_date_position == 'below') {
1954
- if($cff_show_date && $cff_post_type == 'event') $cff_post_item .= $cff_date;
1955
  }
1956
 
1957
- //MEDIA LINK
1958
- if($cff_show_media_link) $cff_post_item .= $cff_media_link;
1959
- //VIEW ON FACEBOOK LINK
1960
- if($cff_show_link) $cff_post_item .= $cff_link;
1961
-
1962
- //End the post item
1963
- $cff_post_item .= '</div>';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1964
 
1965
- //PUSH TO ARRAY
1966
- $cff_posts_array = cff_array_push_assoc($cff_posts_array, $i_post, $cff_post_item);
1967
 
1968
- } // End post type check
1969
 
1970
- if (isset($news->message)) $prev_post_message = $news->message;
1971
- if (isset($news->link)) $prev_post_link = $news->link;
1972
- if (isset($news->description)) $prev_post_description = $news->description;
1973
 
1974
- } // End the loop
 
1975
 
1976
  //Sort the array in reverse order (newest first)
1977
  if(!$cff_is_group) ksort($cff_posts_array);
@@ -2050,11 +2107,18 @@ function cff_desc_tags($description){
2050
 
2051
  return $cff_description_tagged;
2052
  }
 
 
 
 
2053
 
2054
  //Get JSON object of feed data
2055
  function cff_fetchUrl($url){
2056
  $response = wp_remote_get($url);
2057
  $feedData = wp_remote_retrieve_body( $response );
 
 
 
2058
  return $feedData;
2059
  }
2060
 
3
  Plugin Name: Smash Balloon Custom Facebook Feed
4
  Plugin URI: https://smashballoon.com/custom-facebook-feed
5
  Description: Add completely customizable Facebook feeds to your WordPress site
6
+ Version: 2.12
7
  Author: Smash Balloon
8
  Author URI: http://smashballoon.com/
9
  License: GPLv2 or later
24
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25
  */
26
 
27
+ define('CFFVER', '2.12');
28
 
29
  // Db version.
30
  if ( ! defined( 'CFF_DBVERSION' ) ) {
106
  'locale' => get_option('cff_locale'),
107
  'ajax' => get_option('cff_ajax'),
108
  'offset' => '',
109
+ 'account' => '',
110
 
111
  //General
112
  'width' => isset($options[ 'cff_feed_width' ]) ? $options[ 'cff_feed_width' ] : '',
711
  $title_limit = $atts['textlength'];
712
  if (!isset($title_limit)) $title_limit = 9999;
713
  $body_limit = $atts['desclength'];
714
+
715
  //Assign the Access Token and Page ID variables
716
  $access_token = $atts['accesstoken'];
717
  $page_id = trim( $atts['id'] );
718
 
719
+
720
+
721
+ //If an 'account' is specified then use that instead of the Page ID/token from the settings
722
+ $cff_account = trim($atts['account']);
723
+ if( !empty( $cff_account ) ){
724
+ $cff_connected_accounts = get_option('cff_connected_accounts');
725
+ if( !empty($cff_connected_accounts) ){
726
+
727
+ $cff_connected_accounts = json_decode( str_replace('\"','"', $cff_connected_accounts) );
728
+
729
+ //Grab the ID and token from the connected accounts setting
730
+ $page_id = $cff_connected_accounts->{ $cff_account }->{'id'};
731
+ $access_token = $cff_connected_accounts->{ $cff_account }->{'accesstoken'};
732
+
733
+ //Replace the encryption string in the Access Token
734
+ if (strpos($access_token, '02Sb981f26534g75h091287a46p5l63') !== false) {
735
+ $access_token = str_replace("02Sb981f26534g75h091287a46p5l63","",$access_token);
736
+ }
737
+ }
738
+ }
739
+
740
  //If user pastes their full URL into the Page ID field then strip it out
741
  $cff_facebook_string = 'facebook.com';
742
  $cff_page_id_url_check = stripos($page_id, $cff_facebook_string);
748
  $page_id = substr( $page_id, strrpos( $page_id, '/' )+1 );
749
  }
750
 
 
 
751
  //Masonry
752
  $masonry = false;
753
  $cff_cols = $atts['cols'];
780
  }
781
  }
782
 
 
 
783
  //If the Page ID contains a query string at the end then remove it
784
  if ( stripos( $page_id, '?') !== false ) $page_id = substr($page_id, 0, strrpos($page_id, '?'));
785
 
1011
 
1012
  //Check whether any data is returned from the API. If it isn't then don't cache the error response and instead keep checking the API on every page load until data is returned.
1013
  $FBdata = json_decode($posts_json);
 
1014
 
1015
+ if( !empty($FBdata) ) {
1016
+
1017
+ //Error returned by API
1018
+ if( isset($FBdata->error) ){
1019
+
1020
+ //Cache the error JSON so doesn't keep making repeated requests
1021
+ //See if a backup cache exists
1022
+ if ( false !== get_transient( '!cff_' . $transient_name ) ) {
1023
+
1024
+ $posts_json = get_transient( '!cff_' . $transient_name );
1025
+
1026
+ //Add error message to backup cache so can be displayed at top of feed
1027
+ isset( $FBdata->error->message ) ? $error_message = $FBdata->error->message : $error_message = '';
1028
+ isset( $FBdata->error->type ) ? $error_type = $FBdata->error->type : $error_type = '';
1029
+ $prefix = '{';
1030
+ if (substr($posts_json, 0, strlen($prefix)) == $prefix) $posts_json = substr($posts_json, strlen($prefix));
1031
+ $posts_json = '{"cached_error": { "message": "'.$error_message.'", "type": "'.$error_type.'" }, ' . $posts_json;
1032
+ }
1033
+
1034
+ //Posts data returned by API
1035
+ } else {
1036
+ //If a backup should be created for this data then create one
1037
+ set_transient( '!cff_' . $transient_name, $posts_json, YEAR_IN_SECONDS );
1038
  }
1039
+
1040
+ //Set regular cache
1041
+ set_transient( $transient_name, $posts_json, $cache_seconds );
1042
 
1043
  }
1044
  } else {
1045
+
1046
  $posts_json = get_transient( $transient_name );
1047
  //If we can't find the transient then fall back to just getting the json from the api
1048
  if ($posts_json == false) $posts_json = cff_fetchUrl($cff_posts_json_url);
1049
+
1050
  }
1051
  } else {
1052
  $posts_json = cff_fetchUrl($cff_posts_json_url);
1057
  $FBdata = json_decode($posts_json);
1058
 
1059
  //If there's no data then show a pretty error message
1060
+ if( empty($FBdata->data) || isset($FBdata->cached_error) ) {
1061
+
1062
+ //Check whether it's an error in the backup cache
1063
+ if( isset($FBdata->cached_error) ) $FBdata->error = $FBdata->cached_error;
1064
+
1065
+ //Show custom message for the PPCA error
1066
+ if( isset($FBdata->error->message) && strpos($FBdata->error->message, 'Page Public Content Access') !== false ) {
1067
+ $FBdata->error->message = '(#10) To use "Page Public Content Access", your use of this endpoint must be reviewed and approved by Facebook.';
1068
+ $FBdata->error->type = $FBdata->error->code = $FBdata->error->error_subcode = NULL;
1069
+ }
1070
+
1071
+ $cff_content .= '<div class="cff-error-msg">';
1072
+ $cff_content .= '<p><b>This message is only visible to admins.</b><br />';
1073
+ $cff_content .= '<p>Problem displaying Facebook posts.';
1074
+ if( isset($FBdata->cached_error) ) $cff_content .= ' Backup cache in use.';
1075
+ $cff_content .= '<br/><a href="javascript:void(0);" id="cff-show-error" onclick="cffShowError()">Click to show error</a>';
1076
  $cff_content .= '<script type="text/javascript">function cffShowError() { document.getElementById("cff-error-reason").style.display = "block"; document.getElementById("cff-show-error").style.display = "none"; }</script>';
1077
  $cff_content .= '</p><div id="cff-error-reason">';
1078
 
1079
+ if( isset($FBdata->error->message) ) $cff_content .= '<b>Error:</b> ' . $FBdata->error->message;
1080
+ if( isset($FBdata->error->type) ) $cff_content .= '<br /><b>Type:</b> ' . $FBdata->error->type;
 
1081
  if( isset($FBdata->error->error_subcode) ) $cff_content .= '<br />Subcode: ' . $FBdata->error->error_subcode;
1082
 
1083
+ if( isset($FBdata->error_msg) ) $cff_content .= '<b>Error:</b> ' . $FBdata->error_msg;
1084
  if( isset($FBdata->error_code) ) $cff_content .= '<br />Code: ' . $FBdata->error_code;
1085
 
1086
+ if($FBdata == null) $cff_content .= '<b>Error:</b> Server configuration issue';
1087
+ if( empty($FBdata->error) && empty($FBdata->error_msg) && $FBdata !== null ) $cff_content .= '<b>Error:</b> No posts available for this Facebook ID';
1088
+ $cff_content .= '<br /><b>Solution:</b> <a href="https://smashballoon.com/custom-facebook-feed/docs/errors/" target="_blank">See here</a> for how to solve this error';
 
 
 
1089
  $cff_content .= '</div></div>'; //End .cff-error-msg and #cff-error-reason
1090
  //Only display errors to admins
1091
  if( current_user_can( 'manage_options' ) ){
1092
  $cff_content .= '<style>#cff .cff-error-msg{ display: block !important; }</style>';
1093
  }
 
 
 
1094
  }
1095
 
1096
 
1104
  }
1105
 
1106
  //***STARTS POSTS LOOP***
1107
+ if( isset($FBdata->data) ){
1108
+ foreach ($FBdata->data as $news )
1109
+ {
1110
+ //Explode News and Page ID's into 2 values
1111
+ $PostID = '';
1112
+ $cff_post_id = '';
1113
+ if( isset($news->id) ){
1114
+ $cff_post_id = $news->id;
1115
+ $PostID = explode("_", $cff_post_id);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1116
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1117
 
1118
+ //Reassign variable changes from API v3.3 update
1119
+ $news->link = '';
1120
+ $news->description = '';
1121
+ $news->name = '';
1122
+ $news->caption = '';
1123
+ $news->source = '';
1124
+ $news->object_id = '';
1125
+ if( isset($news->attachments->data[0]->unshimmed_url) ) $news->link = $news->attachments->data[0]->unshimmed_url;
1126
+ if( isset($news->attachments->data[0]->description) ) $news->description = $news->attachments->data[0]->description;
1127
+ if( isset($news->attachments->data[0]->target->id) ) $news->object_id = $news->attachments->data[0]->target->id;
1128
+ if( isset($news->attachments->data[0]->media->source) ) $news->source = $news->attachments->data[0]->media->source;
1129
+ if( isset($news->attachments->data[0]->title) ){
1130
+ $news->name = $news->attachments->data[0]->title;
1131
+ $news->caption = $news->attachments->data[0]->title;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1132
  }
1133
 
1134
  //Check the post type
1135
+ $cff_post_type = 'status';
1136
+ if( isset($news->attachments->data[0]->media_type) ) $cff_post_type = $news->attachments->data[0]->media_type;
1137
+
1138
  if ($cff_post_type == 'link') {
1139
  isset($news->story) ? $story = $news->story : $story = '';
1140
  //Check whether it's an event
1141
  $event_link_check = "facebook.com/events/";
1142
+ if( isset($news->link) ){
1143
+ $event_link_check = stripos($news->link, $event_link_check);
1144
+ if ( $event_link_check ) $cff_post_type = 'event';
1145
+ }
1146
  }
1147
 
1148
+ //Should we show this post or not?
1149
+ $cff_show_post = false;
1150
+ switch ($cff_post_type) {
1151
+ case 'link':
1152
+ if ( $cff_show_links_type ) $cff_show_post = true;
1153
+ break;
1154
+ case 'event':
1155
+ if ( $cff_show_event_type ) $cff_show_post = true;
1156
+ break;
1157
+ case 'video':
1158
+ if ( $cff_show_video_type ) $cff_show_post = true;
1159
+ break;
1160
+ case 'swf':
1161
+ if ( $cff_show_video_type ) $cff_show_post = true;
1162
+ break;
1163
+ case 'photo':
1164
+ if ( $cff_show_photos_type ) $cff_show_post = true;
1165
+ break;
1166
+ case 'offer':
1167
+ $cff_show_post = true;
1168
+ break;
1169
+ default:
1170
+ //Check whether it's a status (author comment or like)
1171
+ if ( $cff_show_status_type && !empty($news->message) ) $cff_show_post = true;
1172
+ break;
1173
  }
1174
 
1175
+ //Is it a duplicate post?
1176
+ if (!isset($prev_post_message)) $prev_post_message = '';
1177
+ if (!isset($prev_post_link)) $prev_post_link = '';
1178
+ if (!isset($prev_post_description)) $prev_post_description = '';
1179
+ isset($news->message) ? $pm = $news->message : $pm = '';
1180
+ isset($news->link) ? $pl = $news->link : $pl = '';
1181
+ isset($news->description) ? $pd = $news->description : $pd = '';
1182
+
1183
+ if ( ($prev_post_message == $pm) && ($prev_post_link == $pl) && ($prev_post_description == $pd) ) $cff_show_post = false;
1184
+
1185
+ //Offset. If the post index ($i_post) is less than the offset then don't show the post
1186
+ if( intval($i_post) < intval($atts['offset']) ){
1187
+ $cff_show_post = false;
1188
+ $i_post++;
1189
  }
1190
 
1191
+ //Check post type and display post if selected
1192
+ if ( $cff_show_post ) {
1193
+ //If it isn't then create the post
1194
+ //Only create posts for the amount of posts specified
1195
+ if( intval($atts['offset']) > 0 ){
1196
+ //If offset is being used then stop after showing the number of posts + the offset
1197
+ if ( $i_post == (intval($show_posts) + intval($atts['offset'])) ) break;
1198
  } else {
1199
+ //Else just stop after the number of posts to be displayed is reached
1200
+ if ( $i_post == $show_posts ) break;
1201
+ }
1202
+ $i_post++;
1203
+ //********************************//
1204
+ //***COMPILE SECTION VARIABLES***//
1205
+ //********************************//
1206
+ //Set the post link
1207
+ isset($news->link) ? $link = htmlspecialchars($news->link) : $link = '';
1208
+ //Is it a shared album?
1209
+ $shared_album_string = 'shared an album:';
1210
+ isset($news->story) ? $story = $news->story : $story = '';
1211
+ $shared_album = stripos($story, $shared_album_string);
1212
+ if ( $shared_album ) {
1213
+ $link = str_replace('photo.php?','media/set/?',$link);
1214
  }
 
1215
 
1216
+ //Check the post type
1217
+ isset($cff_post_type) ? $cff_post_type = $cff_post_type : $cff_post_type = '';
1218
+ if ($cff_post_type == 'link') {
1219
+ isset($news->story) ? $story = $news->story : $story = '';
1220
+ //Check whether it's an event
1221
+ $event_link_check = "facebook.com/events/";
1222
+ //Make sure URL doesn't include 'permalink' as that indicates someone else sharing a post from within an event (eg: https://www.facebook.com/events/617323338414282/permalink/617324268414189/) and the event ID is then not retrieved properly from the event URL as it's formatted like so: facebook.com/events/EVENT_ID/permalink/POST_ID
1223
+ $event_link_check = stripos($news->link, $event_link_check);
1224
+ $event_link_check_2 = stripos($news->link, "permalink/");
1225
+ if ( $event_link_check && !$event_link_check_2 ) $cff_post_type = 'event';
1226
+ }
1227
 
1228
+ //If it's an event then check whether the URL contains facebook.com
1229
+ if(isset($news->link)){
1230
+ if( stripos($news->link, "events/") && $cff_post_type == 'event' ){
1231
+ //Facebook changed the event link from absolute to relative, and so if the link isn't absolute then add facebook.com to front
1232
+ ( stripos($link, 'facebook.com') ) ? $link = $link : $link = 'https://facebook.com' . $link;
1233
+ }
1234
+ }
1235
 
1236
+ //Is it an album?
1237
+ $cff_album = false;
1238
+ if( isset($news->status_type) ){
1239
+ if( $news->status_type == 'added_photos' ){
1240
+ if( isset($news->attachments) ){
1241
+ if( $news->attachments->data[0]->media_type == 'album' ) $cff_album = true;
1242
+ }
1243
+ }
1244
+ }
1245
 
1246
+ //If there's no link provided then link to either the Facebook page or the individual status
1247
+ if (empty($news->link)) {
1248
+ if ($cff_link_to_timeline == true){
1249
+ //Link to page
1250
+ $link = 'https://facebook.com/' . $page_id;
1251
+ } else {
1252
+ //Link to status
1253
+ $link = "https://www.facebook.com/" . $page_id . "/posts/" . $PostID[1];
1254
+ }
1255
+ }
1256
 
1257
+ //DATE
1258
+ $cff_date_formatting = $atts[ 'dateformat' ];
1259
+ $cff_date_custom = $atts[ 'datecustom' ];
 
 
 
 
 
 
1260
 
1261
+ isset($news->created_time) ? $post_time = $news->created_time : $post_time = '';
1262
+ if( isset($news->backdated_time) ) $post_time = $news->backdated_time; //If the post is backdated then use that as the date instead
1263
 
1264
+ $cff_date = '<p class="cff-date" '.$cff_date_styles.'>'. $cff_date_before . ' ' . cff_getdate(strtotime($post_time), $cff_date_formatting, $cff_date_custom, $cff_date_translate_strings) . ' ' . $cff_date_after;
1265
+ if($cff_date_position == 'below' || (!$cff_show_author && $cff_date_position == 'author') ) $cff_date .= '<span class="cff-date-dot">&nbsp;&middot;&nbsp;&nbsp;</span>';
1266
+ $cff_date .= '</p>';
 
 
1267
 
1268
+ //Page name
1269
+ if( isset($news->from->name) ){
1270
+ $cff_author_name = $news->from->name;
1271
+ $cff_author_name = str_replace('"', "", $cff_author_name);
1272
+ } else {
1273
+ $cff_author_name = '';
1274
+ }
1275
 
1276
+ //Story/post text vars
1277
+ $post_text = '';
1278
+ $cff_post_text_type = '';
1279
+ $cff_story_raw = '';
1280
+ $cff_message_raw = '';
1281
+ $cff_name_raw = '';
1282
+ $text_tags = '';
1283
+ $post_text_story = '';
1284
+ $post_text_message = '';
1285
 
1286
+ //STORY TAGS
1287
+ $cff_post_tags = $atts[ 'posttags' ];
1288
 
1289
+ //Use the story
1290
+ if (!empty($news->story)) {
1291
+ $cff_story_raw = $news->story;
1292
+ $post_text_story .= htmlspecialchars($cff_story_raw);
1293
+ $cff_post_text_type = 'story';
1294
 
 
 
1295
 
1296
+ //Add message and story tags if there are any and the post text is the message or the story
1297
+ if( $cff_post_tags && isset($news->story_tags) && !$cff_title_link){
1298
+
1299
+ $text_tags = $news->story_tags;
1300
 
1301
+ //Does the Post Text contain any html tags? - the & symbol is the best indicator of this
1302
+ $cff_html_check_array = array('&lt;', '’', '“', '&quot;', '&amp;', '&gt;&gt;');
1303
 
1304
+ //always use the text replace method
1305
+ if( cff_stripos_arr($post_text_story, $cff_html_check_array) !== false || ($cff_locale == 'el_GR' && count($news->story_tags) > 3) ) {
1306
 
1307
+ //Loop through the tags
1308
+ foreach($text_tags as $message_tag ) {
1309
 
1310
+ ( isset($message_tag->id) ) ? $message_tag = $message_tag : $message_tag = $message_tag[0];
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1311
 
1312
+ $tag_name = $message_tag->name;
1313
+ $tag_link = '<a href="https://facebook.com/' . $message_tag->id . '">' . $message_tag->name . '</a>';
1314
+
1315
+ $post_text_story = str_replace($tag_name, $tag_link, $post_text_story);
 
 
 
 
 
 
 
1316
  }
 
 
1317
 
1318
+ } else {
1319
+
1320
+ //If it doesn't contain HTMl tags then use the offset to replace message tags
1321
+ $message_tags_arr = array();
1322
+
1323
+ $tag = 0;
1324
+ foreach($text_tags as $message_tag ) {
1325
+ $tag++;
1326
+ ( isset($message_tag->id) ) ? $message_tag = $message_tag : $message_tag = $message_tag[0];
1327
+
1328
+ isset($message_tag->type) ? $tag_type = $message_tag->type : $tag_type = '';
1329
+
1330
+ $message_tags_arr = cff_array_push_assoc(
1331
+ $message_tags_arr,
1332
+ $tag,
1333
+ array(
1334
+ 'id' => $message_tag->id,
1335
+ 'name' => $message_tag->name,
1336
+ 'type' => isset($message_tag->type) ? $message_tag->type : '',
1337
+ 'offset' => $message_tag->offset,
1338
+ 'length' => $message_tag->length
1339
+ )
1340
+ );
1341
+
1342
+ }
1343
 
1344
+ //Keep track of the offsets so that if two tags have the same offset then only one is used. Need this as API 2.5 update changed the story_tag JSON format. A duplicate offset usually means '__ was with __ and 3 others'. We don't want to link the '3 others' part.
1345
+ $cff_story_tag_offsets = '';
1346
+ $cff_story_duplicate_offset = '';
1347
 
1348
+ //Check if there are any duplicate offsets. If so, assign to the cff_story_duplicate_offset var.
1349
+ for($tag = count($message_tags_arr); $tag >= 1; $tag--) {
1350
+ $c = (string)$message_tags_arr[$tag]['offset'];
1351
+ if( strpos( $cff_story_tag_offsets, $c ) !== false && $c !== '0' ){
1352
+ $cff_story_duplicate_offset = $c;
1353
  } else {
1354
+ $cff_story_tag_offsets .= $c . ',';
 
 
 
1355
  }
1356
+
1357
  }
1358
 
1359
+ for($tag = count($message_tags_arr); $tag >= 1; $tag--) {
 
 
1360
 
1361
+ //If the name is blank (aka the story tag doesn't work properly) then don't use it
1362
+ if( $message_tags_arr[$tag]['name'] !== '' ) {
1363
 
1364
+ //If it's an event tag or it has the same offset as another tag then don't display it
1365
+ if( $message_tags_arr[$tag]['type'] == 'event' || $message_tags_arr[$tag]['offset'] == $cff_story_duplicate_offset || $message_tags_arr[$tag]['type'] == 'page' ){
1366
+ //Don't use the story tag in this case otherwise it changes '__ created an event' to '__ created an Name Of Event'
1367
+ //Don't use the story tag if it's a page as it causes an issue when sharing a page: Smash Balloon Dev shared a Smash Balloon.
1368
+ } else {
1369
+ $b = '<a href="https://facebook.com/' . $message_tags_arr[$tag]['id'] . '" target="_blank">' . $message_tags_arr[$tag]['name'] . '</a>';
1370
+ $c = $message_tags_arr[$tag]['offset'];
1371
+ $d = $message_tags_arr[$tag]['length'];
1372
+ $post_text_story = cff_mb_substr_replace( $post_text_story, $b, $c, $d);
1373
+ }
1374
 
1375
+ }
1376
 
1377
+ }
1378
+
1379
+ } // end if/else
 
1380
 
1381
+ } //END STORY TAGS
 
 
1382
 
 
 
 
 
1383
  }
1384
+
1385
+ //POST AUTHOR
1386
+ $cff_author = '';
1387
+ if( isset($news->from->id) ){
1388
 
1389
+ $cff_author .= '<div class="cff-author">';
1390
+
1391
+ //Check if the author from ID exists, as sometimes it doesn't
1392
+ isset($news->from->id) ? $cff_from_id = $news->from->id : $cff_from_id = '';
1393
+
1394
+ $cff_author_link_atts = 'href="https://facebook.com/' . $cff_from_id . '" '.$target.$cff_nofollow.' '.$cff_author_styles;
1395
+
1396
+ //Link to the post if it's a visitor post as profile link no longer available
1397
+ $cff_author_link_el = 'a';
1398
+ $cff_author_link_atts = ' href="https://facebook.com/' . $cff_from_id . '" '.$target.$cff_nofollow.' '.$cff_author_styles;
1399
+
1400
+ //If no link is available then change to span
1401
+ if( !isset($news->from->link) ){
1402
+ $cff_author_link_el = 'span';
1403
+ $cff_author_link_atts = '';
1404
  }
 
 
 
 
 
 
 
 
 
 
1405
 
1406
+ //Remove the first occurence of the author name from the story
1407
+ if( !empty($cff_author_name) ){
1408
+ $cff_author_name_pos = strpos($post_text_story, $cff_author_name);
1409
+ if ($cff_author_name_pos !== false) {
1410
+ $post_text_story = substr_replace($post_text_story, '', $cff_author_name_pos, strlen($cff_author_name));
1411
+ }
1412
+ }
1413
+
1414
+ //Author text
1415
+ $cff_author .= '<div class="cff-author-text">';
1416
+ if($cff_show_date && $cff_date_position !== 'above' && $cff_date_position !== 'below'){
1417
+ $cff_author .= '<p class="cff-page-name cff-author-date" '.$cff_author_styles.'><'.$cff_author_link_el.$cff_author_link_atts.'>'.$cff_author_name.'</'.$cff_author_link_el.'><span class="cff-story"> '.$post_text_story.'</span></p>';
1418
+ $cff_author .= $cff_date;
1419
+ } else {
1420
+ $cff_author .= '<span class="cff-page-name"><'.$cff_author_link_el.$cff_author_link_atts.'>'.$cff_author_name.'</'.$cff_author_link_el.'><span class="cff-story"> '.$post_text_story.'</span></span>';
1421
+ }
1422
 
1423
+ $cff_author .= '</div>';
 
1424
 
1425
+ //Author image
1426
+ isset($news->from->picture->data->url) ? $cff_author_src = $news->from->picture->data->url : $cff_author_src = '';
1427
 
1428
+ $cff_author .= '<div class="cff-author-img"><'.$cff_author_link_el.$cff_author_link_atts.'><img src="'.$cff_author_src.'" title="'.$cff_author_name.'" alt="'.$cff_author_name.'" width=40 height=40 onerror="this.style.display=\'none\'"></'.$cff_author_link_el.'></div>';
1429
 
1430
+ $cff_author .= '</div>'; //End .cff-author
1431
 
 
 
 
 
 
 
 
1432
  } else {
 
 
 
1433
 
1434
+ $cff_author .= '<div class="cff-author cff-no-author-info">';
1435
+
1436
+ //Author text
1437
+ $cff_author .= '<div class="cff-author-text">';
1438
+ if($cff_show_date && $cff_date_position !== 'above' && $cff_date_position !== 'below'){
1439
+ if( !empty($post_text_story) ) $cff_author .= '<p class="cff-page-name cff-author-date"><span class="cff-story"> '.$post_text_story.'</span></p>';
1440
+ $cff_author .= $cff_date;
1441
+ } else {
1442
+ if( !empty($post_text_story) ) $cff_author .= '<span class="cff-page-name"><span class="cff-story"> '.$post_text_story.'</span></span>';
1443
+ }
1444
+ $cff_author .= '</div>';
1445
 
1446
+ //Author image
1447
+ $cff_author .= '<div class="cff-author-img"></div>';
1448
+ $cff_author .= '</div>'; //End .cff-author
1449
 
1450
+ }
1451
 
 
 
 
 
 
 
 
 
 
 
1452
 
1453
+ //POST TEXT
1454
+
1455
+ //Get the actual post text
1456
+ //Which content should we use?
1457
+ //Use the message
1458
+ if (!empty($news->message)) {
1459
+ $cff_message_raw = $news->message;
1460
 
1461
+ $post_text_message = htmlspecialchars($cff_message_raw);
1462
+ $cff_post_text_type = 'message';
 
 
1463
 
1464
+ //MESSAGE TAGS
1465
+ //Add message and story tags if there are any and the post text is the message or the story
1466
+ if( $cff_post_tags && isset($news->message_tags) && !$cff_title_link){
1467
+
1468
+ $text_tags = $news->message_tags;
1469
 
1470
+ //Does the Post Text contain any html tags? - the & symbol is the best indicator of this
1471
+ $cff_html_check_array = array('&lt;', '’', '“', '&quot;', '&amp;', '&gt;&gt;', '&gt;');
1472
 
1473
+ //always use the text replace method
1474
+ if( cff_stripos_arr($post_text_message, $cff_html_check_array) !== false ) {
1475
+ //Loop through the tags
1476
+ foreach($text_tags as $message_tag ) {
1477
 
1478
+ ( isset($message_tag->id) ) ? $message_tag = $message_tag : $message_tag = $message_tag[0];
 
1479
 
1480
+ $tag_name = $message_tag->name;
1481
+ $tag_link = '<a href="https://facebook.com/' . $message_tag->id . '">' . $message_tag->name . '</a>';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1482
 
1483
+ $post_text_message = str_replace($tag_name, $tag_link, $post_text_message);
 
 
 
 
 
 
 
 
 
 
1484
  }
 
1485
 
1486
+ } else {
1487
+ //If it doesn't contain HTMl tags then use the offset to replace message tags
1488
+ $message_tags_arr = array();
1489
+
1490
+ $tag = 0;
1491
+ foreach($text_tags as $message_tag ) {
1492
+ $tag++;
1493
+
1494
+ ( isset($message_tag->id) ) ? $message_tag = $message_tag : $message_tag = $message_tag[0];
1495
+
1496
+ $message_tags_arr = cff_array_push_assoc(
1497
+ $message_tags_arr,
1498
+ $tag,
1499
+ array(
1500
+ 'id' => $message_tag->id,
1501
+ 'name' => $message_tag->name,
1502
+ 'type' => isset($message_tag->type) ? $message_tag->type : '',
1503
+ 'offset' => $message_tag->offset,
1504
+ 'length' => $message_tag->length
1505
+ )
1506
+ );
1507
+ }
1508
 
1509
+ //Keep track of the offsets so that if two tags have the same offset then only one is used. Need this as API 2.5 update changed the story_tag JSON format.
1510
+ $cff_msg_tag_offsets = '';
1511
+ $cff_msg_duplicate_offset = '';
1512
 
1513
+ //Check if there are any duplicate offsets. If so, assign to the cff_duplicate_offset var.
1514
+ for($tag = count($message_tags_arr); $tag >= 1; $tag--) {
1515
+ $c = (string)$message_tags_arr[$tag]['offset'];
1516
+ if( strpos( $cff_msg_tag_offsets, $c ) !== false && $c !== '0' ){
1517
+ $cff_msg_duplicate_offset = $c;
1518
  } else {
1519
+ $cff_msg_tag_offsets .= $c . ',';
 
 
 
1520
  }
 
1521
  }
1522
 
1523
+ //Sort the array by the "offset" key as Facebook doesn't always return them in the correct order
1524
+ usort($message_tags_arr, "cffSortTags");
1525
 
1526
+ for($tag = count($message_tags_arr)-1; $tag >= 0; $tag--) {
1527
 
1528
+ //If the name is blank (aka the story tag doesn't work properly) then don't use it
1529
+ if( $message_tags_arr[$tag]['name'] !== '' ) {
1530
 
1531
+ if( $message_tags_arr[$tag]['offset'] == $cff_msg_duplicate_offset ){
1532
+ //If it has the same offset as another tag then don't display it
1533
+ } else {
1534
+ $b = '<a href="https://facebook.com/' . $message_tags_arr[$tag]['id'] . '">' . $message_tags_arr[$tag]['name'] . '</a>';
1535
+ $c = $message_tags_arr[$tag]['offset'];
1536
+ $d = $message_tags_arr[$tag]['length'];
1537
+ $post_text_message = cff_mb_substr_replace( $post_text_message, $b, $c, $d);
1538
+ }
1539
 
1540
+ }
1541
+
1542
+ }
1543
+
1544
+ } // end if/else
1545
+
1546
+ } //END MESSAGE TAGS
1547
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1548
  }
 
 
1549
 
 
 
 
1550
 
1551
+ //Check to see whether it's an embedded video so that we can show the name above the post text if necessary
1552
+ $cff_soundcloud = false;
1553
+ $cff_is_video_embed = false;
1554
+ if ($cff_post_type == 'video' || $cff_post_type == 'music'){
1555
+ if( isset($news->source) && !empty($news->source) ){
1556
+ $url = $news->source;
1557
+ } else if ( isset($news->link) ) {
1558
+ $url = $news->link;
1559
+ } else {
1560
+ $url = '';
1561
+ }
1562
+ //Embeddable video strings
1563
+ $youtube = 'youtube';
1564
+ $youtu = 'youtu';
1565
+ $vimeo = 'vimeo';
1566
+ $youtubeembed = 'youtube.com/embed';
1567
+ $soundcloud = 'soundcloud.com';
1568
+ $swf = '.swf';
1569
+ //Check whether it's a youtube video
1570
+ $youtube = stripos($url, $youtube);
1571
+ $youtu = stripos($url, $youtu);
1572
+ $youtubeembed = stripos($url, $youtubeembed);
1573
+ //Check whether it's a SoundCloud embed
1574
+
1575
+ $soundcloudembed = stripos($url, $soundcloud);
1576
+ //Check whether it's a youtube video
1577
+ if($youtube || $youtu || $youtubeembed || (stripos($url, $vimeo) !== false)) {
1578
+ $cff_is_video_embed = true;
1579
+ }
1580
+ //If it's soundcloud then add it into the shared link box at the bottom of the post
1581
+ if( $soundcloudembed ) $cff_soundcloud = true;
1582
+
1583
+ $cff_video_name = '';
1584
+ //If the name exists and it's a non-embedded video then show the name at the top of the post text
1585
+ if( isset($news->name) && !$cff_is_video_embed ){
1586
+
1587
+ if (!$cff_title_link) $cff_video_name .= '<a href="'.$link.'" '.$target.$cff_nofollow.' style="color: #'.$cff_posttext_link_color.'">';
1588
+ $cff_video_name .= htmlspecialchars($news->name);
1589
+ if (!$cff_title_link) $cff_video_name .= '</a>';
1590
+ $cff_video_name .= '<br />';
1591
 
1592
+ //Only show the video name if there's no post text
1593
+ if( empty($post_text_message) || $post_text_message == '' || strlen($post_text_message) < 1 ){
1594
 
1595
+ //If there's no description then show the video name above the post text, otherwise we'll show it below
1596
+ if( empty($cff_description) || $cff_description == '' ) $post_text = $cff_video_name;
1597
 
1598
+ }
1599
  }
1600
  }
 
1601
 
1602
+ //Add the story and message together
1603
+ $post_text = '';
1604
 
1605
+ //DESCRIPTION
1606
+ $cff_description = '';
1607
+ if ( !empty($news->description) || !empty($news->caption) ) {
1608
+ $description_text = '';
1609
 
1610
+ if ( !empty($news->description) ) {
1611
+ $description_text = $news->description;
1612
+ }
1613
 
1614
+ //Replace ellipsis char in description text
1615
+ $description_text = str_replace( '…','...', $description_text);
 
 
 
 
1616
 
1617
+ //If the description is the same as the post text then don't show it
1618
+ if( $description_text == $cff_story_raw || $description_text == $cff_message_raw || $description_text == $cff_name_raw ){
1619
+ $cff_description = '';
1620
  } else {
1621
+ //Add links and create HTML
1622
+ $cff_description .= '<span class="cff-post-desc" '.$cff_body_styles.'>';
1623
+
1624
+ if ($cff_title_link) {
1625
+ $cff_description_tagged = cff_wrap_span( htmlspecialchars($description_text) );
1626
+ } else {
1627
+ $cff_description_text = cff_autolink( htmlspecialchars($description_text), $link_color=$cff_posttext_link_color );
1628
+ $cff_description_tagged = cff_desc_tags($cff_description_text);
1629
+ }
1630
+
1631
+ $cff_description .= $cff_description_tagged;
1632
+ $cff_description .= ' </span>';
1633
  }
1634
 
1635
+ if( $cff_post_type == 'event' || $cff_is_video_embed || $cff_soundcloud ) $cff_description = '';
 
1636
  }
 
 
 
1637
 
1638
+ //Add the message
1639
+ if($cff_show_text) $post_text .= $post_text_message;
1640
 
1641
+ //If it's a shared video post then add the video name after the post text above the video description so it's all one chunk
1642
+ if ($cff_post_type == 'video'){
1643
+ if( !empty($cff_description) && $cff_description != '' ){
1644
+ if( (!empty($post_text) && $post_text != '') && !empty($cff_video_name) ) $post_text .= '<br /><br />';
1645
+ $post_text .= $cff_video_name;
1646
+ }
1647
  }
 
1648
 
1649
 
1650
+ //Use the name
1651
+ if (!empty($news->name) && empty($news->message)) {
1652
+ $cff_name_raw = $news->name;
1653
+ $post_text = htmlspecialchars($cff_name_raw);
1654
+ $cff_post_text_type = 'name';
1655
+ }
1656
 
1657
+ //OFFER TEXT
1658
+ if ($cff_post_type == 'offer'){
1659
+ isset($news->story) ? $post_text = htmlspecialchars($news->story) . '<br /><br />' : $post_text = '';
1660
+ $post_text .= htmlspecialchars($news->name);
1661
+ $cff_post_text_type = 'story';
1662
+ }
1663
 
1664
+ //Add the description
1665
+ if( $cff_show_desc && $cff_post_type != 'offer' && $cff_post_type != 'link' ) $post_text .= $cff_description;
1666
 
1667
+ //Change the linebreak element if the text issue setting is enabled
1668
+ $cff_format_issue = $atts['textissue'];
1669
+ ($cff_format_issue == 'true' || $cff_format_issue == 'on') ? $cff_format_issue = true : $cff_format_issue = false;
1670
+ $cff_linebreak_el = '<br />';
1671
+ if( $cff_format_issue ) $cff_linebreak_el = '<img class="cff-linebreak" />';
1672
 
1673
+ //EVENT
1674
+ $cff_event_has_cover_photo = false;
1675
+ $cff_event = '';
1676
 
1677
 
1678
+ //Create note
1679
+ if ($cff_post_type == 'note') {
1680
+
1681
+ // Get any existing copy of our transient data from previous versions
1682
+ $transient_name = 'cff_tle_' . $cff_post_id;
1683
+ $transient_name = substr($transient_name, 0, 45);
1684
+ if ( false !== ( $cff_note_json = get_transient( $transient_name ) ) ) {
1685
+ $cff_note_json = get_transient( $transient_name );
1686
+
1687
+ //Interpret data with JSON
1688
+ $cff_note_obj = json_decode($cff_note_json);
1689
+ $cff_note_object = $cff_note_obj->attachments->data[0];
1690
+ isset($cff_note_object->title) ? $cff_note_title = htmlentities($cff_note_object->title, ENT_QUOTES, 'UTF-8') : $cff_note_title = '';
1691
+ isset($cff_note_object->description) ? $cff_note_description = htmlentities($cff_note_object->description, ENT_QUOTES, 'UTF-8') : $cff_note_description = '';
1692
+ isset($cff_note_object->url) ? $cff_note_link = $cff_note_object->url : $cff_note_link = '';
1693
+ isset( $cff_note_object->media->image->src ) ? $cff_note_media_src = $cff_note_object->media->image->src : $cff_note_media_src = false;
1694
+ } else {
1695
+ $attachment_data = '';
1696
+ if(isset($news->attachments->data[0])){
1697
+ $attachment_data = $news->attachments->data[0];
1698
+ isset($attachment_data->title) ? $cff_note_title = htmlentities($attachment_data->title, ENT_QUOTES, 'UTF-8') : $cff_note_title = '';
1699
+ isset($attachment_data->description) ? $cff_note_description = htmlentities($attachment_data->description, ENT_QUOTES, 'UTF-8') : $cff_note_description = '';
1700
+ isset($attachment_data->unshimmed_url) ? $cff_note_link = $attachment_data->unshimmed_url : $cff_note_link = '';
1701
+ $cff_note_media_src = '';
1702
+ }
1703
  }
 
1704
 
1705
 
1706
+ //Note details
1707
+ $cff_note = '<span class="cff-details">';
1708
+ $cff_note = '<span class="cff-note-title">'.$cff_note_title.'</span>';
1709
+ $cff_note .= $cff_note_description;
1710
+ $cff_note .= '</span>';
1711
 
1712
+ //Notes don't include any post text and so just replace the post text with the note content
1713
+ if($cff_show_text) $post_text = $cff_note;
1714
+ }
1715
 
1716
 
1717
+ //Create the HTML for the post text elemtent, if the post has text
1718
+ $cff_post_text = '';
1719
 
1720
+ if( !empty($post_text) ){
1721
+ $cff_post_text = '<' . $cff_title_format . ' class="cff-post-text" ' . $cff_title_styles . '>';
1722
 
1723
+ //Start HTML for post text
1724
+ $cff_post_text .= '<span class="cff-text" data-color="'.$cff_posttext_link_color.'">';
1725
+ if ($cff_title_link){
1726
+ //Link to the Facebook post if it's a link or a video;
1727
+ ($cff_post_type == 'link' || $cff_post_type == 'video') ? $text_link = "https://www.facebook.com/" . $page_id . "/posts/" . $PostID[1] : $text_link = $link;
1728
 
1729
+ $cff_post_text .= '<a class="cff-post-text-link" '.$cff_title_styles.' href="'.$text_link.'" '.$target.$cff_nofollow.'>';
1730
+ }
1731
+
1732
+ //Replace line breaks in text (needed for IE8 and to prevent lost line breaks in HTML minification)
1733
+ $post_text = preg_replace("/\r\n|\r|\n/",$cff_linebreak_el, $post_text);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1734
 
1735
+ //If the text is wrapped in a link then don't hyperlink any text within
1736
+ if ($cff_title_link) {
1737
+ //Remove links from text
1738
+ $result = preg_replace('/<a href=\"(.*?)\">(.*?)<\/a>/', "\\2", $post_text);
1739
+ //Wrap links in a span so we can break the text if it's too long
1740
+ $cff_post_text .= cff_wrap_span( $result ) . ' ';
1741
+ } else {
1742
+ //Don't use htmlspecialchars for post_text as it's added above so that it doesn't mess up the message_tag offsets
1743
+ $cff_post_text .= cff_autolink( $post_text ) . ' ';
1744
+ }
1745
+
1746
+ if ($cff_title_link) $cff_post_text .= '</a>';
1747
+ $cff_post_text .= '</span>';
1748
+ //'See More' link
1749
+ $cff_post_text .= '<span class="cff-expand">... <a href="#" style="color: #'.$cff_posttext_link_color.'"><span class="cff-more">' . $cff_see_more_text . '</span><span class="cff-less">' . $cff_see_less_text . '</span></a></span>';
1750
+ $cff_post_text .= '</' . $cff_title_format . '>';
1751
+
1752
+ //Facebook returns the text as "'s cover photo" for some reason, so ignore it
1753
+ if( $post_text == "'s cover photo" ) $cff_post_text = '';
 
 
 
 
 
 
 
1754
  }
1755
 
1756
+ //Add a call to action button if included
1757
+ if( isset($news->call_to_action->value->link) ){
1758
+ $cff_cta_link = $news->call_to_action->value->link;
1759
+ //If it's not an absolute link then it means it's a relative Facebook one so prefix it with facebook.com
1760
+ if (strpos($cff_cta_link, 'http') === false) $cff_cta_link = 'https://facebook.com' . $cff_cta_link;
1761
+
1762
+ $cff_button_type = $news->call_to_action->type;
1763
+
1764
+ switch ($cff_button_type) {
1765
+ case 'SHOP_NOW':
1766
+ $cff_translate_shop_now_text = $atts['shopnowtext'];
1767
+ if (!isset($cff_translate_shop_now_text) || empty($cff_translate_shop_now_text)) $cff_translate_shop_now_text = 'Shop Now';
1768
+ $cff_cta_button_text = $cff_translate_shop_now_text;
1769
+ break;
1770
+ case 'MESSAGE_PAGE':
1771
+ $cff_translate_message_page_text = $atts['messagepage'];
1772
+ if (!isset($cff_translate_message_page_text) || empty($cff_translate_message_page_text)) $cff_translate_message_page_text = 'Message Page';
1773
+ $cff_cta_button_text = $cff_translate_message_page_text;
1774
+ break;
1775
+ case 'LEARN_MORE':
1776
+ $cff_translate_learn_more_text = $atts['learnmoretext'];
1777
+ if (!isset($cff_translate_learn_more_text) || empty($cff_translate_learn_more_text)) $cff_translate_learn_more_text = 'Learn More';
1778
+ $cff_cta_button_text = $cff_translate_learn_more_text;
1779
+ break;
1780
+ default:
1781
+ $cff_cta_button_text = ucwords(strtolower( str_replace('_',' ',$cff_button_type) ) );
1782
+ }
1783
 
1784
+ isset($news->call_to_action->value->app_link) ? $cff_app_link = $news->call_to_action->value->app_link : $cff_app_link = '';
1785
+ $cff_post_text .= '<p class="cff-cta-link" '.$cff_title_styles.'><a href="'.$cff_cta_link.'" target="_blank" data-app-link="'.$cff_app_link.'" style="color: #'.$cff_posttext_link_color.';" >'.$cff_cta_button_text.'</a></p>';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1786
  }
1787
 
1788
+ //LINK
1789
+ $cff_shared_link = '';
1790
+ //Display shared link
1791
+ if ($cff_post_type == 'link' || $cff_soundcloud || $cff_is_video_embed) {
1792
+
1793
+ $cff_shared_link .= '<div class="cff-shared-link';
1794
+ if($cff_disable_link_box) $cff_shared_link .= ' cff-no-styles';
1795
+
1796
+ $cff_shared_link .= '" ';
1797
+
1798
+ if(!$cff_disable_link_box) $cff_shared_link .= $cff_link_box_styles;
1799
+ $cff_shared_link .= '>';
1800
+ $cff_link_image = '';
1801
+
1802
+ //Display link name and description
1803
+ $cff_shared_link .= '<div class="cff-text-link ';
1804
+ if (!$cff_link_image) $cff_shared_link .= 'cff-no-image';
1805
+ //The link title:
1806
+ if( isset($news->name) ) $cff_shared_link .= '"><'.$cff_link_title_format.' class="cff-link-title" '.$cff_link_title_styles.'><a href="'.$link.'" '.$target.$cff_nofollow.' style="color:#' . $cff_link_title_color . ';">'. $news->name . '</a></'.$cff_link_title_format.'>';
1807
+ //The link source:
1808
+ if( !empty($news->link) ){
1809
+ $cff_link_caption = htmlentities($news->link, ENT_QUOTES, 'UTF-8');
1810
+ $cff_link_caption_parts = explode('/', $cff_link_caption);
1811
+ if( isset($cff_link_caption_parts[2]) ) $cff_link_caption = $cff_link_caption_parts[2];
1812
+ } else {
1813
+ $cff_link_caption = '';
1814
  }
1815
 
1816
+ //Shared link styles
1817
+ $cff_link_url_color_html = '';
1818
+ $cff_link_url_size_html = '';
1819
+ if( isset($cff_link_url_color) && !empty($cff_link_url_color) && $cff_link_url_color != '#' ) $cff_link_url_color_html = 'color: #'.str_replace('#', '', $cff_link_url_color).';';
1820
+ if( $cff_link_url_size != 'inherit' && !empty($cff_link_url_size) ) $cff_link_url_size_html = 'font-size:'.$cff_link_url_size.'px;';
1821
+
1822
+ $cff_link_styles_html = '';
1823
+ if( strlen($cff_link_url_color_html) > 1 || strlen($cff_link_url_size_html) > 1 ) $cff_link_styles_html = 'style="';
1824
+ if( strlen($cff_link_url_color_html) > 1 ) $cff_link_styles_html .= $cff_link_url_color_html;
1825
+ if( strlen($cff_link_url_size_html) > 1 ) $cff_link_styles_html .= $cff_link_url_size_html;
1826
+ if( strlen($cff_link_url_color_html) > 1 || strlen($cff_link_url_size_html) > 1 ) $cff_link_styles_html .= '"';
1827
+
1828
+ if(!empty($cff_link_caption)) $cff_shared_link .= '<p class="cff-link-caption" '.$cff_link_styles_html.'>'.$cff_link_caption.'</p>';
1829
+ if ($cff_show_desc) {
1830
+ //Truncate desc
1831
+ if (!empty($body_limit)) {
1832
+ if (strlen($description_text) > $body_limit) $description_text = substr($description_text, 0, $body_limit) . '...';
1833
+ }
1834
 
1835
+ //Shared link desc styles
1836
+ $cff_link_desc_color_html = '';
1837
+ $cff_link_desc_size_html = '';
1838
+ if( isset($cff_link_desc_color) && !empty($cff_link_desc_color) && $cff_link_desc_color != '#' ) $cff_link_desc_color_html = 'color: #'.str_replace('#', '', $cff_link_desc_color).';';
1839
+ if( $cff_link_desc_size != 'inherit' && !empty($cff_link_desc_size) ) $cff_link_desc_size_html = 'font-size:'.$cff_link_desc_size.'px;';
1840
+
1841
+ $cff_link_desc_styles_html = '';
1842
+ if( strlen($cff_link_desc_color_html) > 1 || strlen($cff_link_desc_size_html) > 1 ) $cff_link_desc_styles_html = 'style="';
1843
+ if( strlen($cff_link_desc_color_html) > 1 ) $cff_link_desc_styles_html .= $cff_link_desc_color_html;
1844
+ if( strlen($cff_link_desc_size_html) > 1 ) $cff_link_desc_styles_html .= $cff_link_desc_size_html;
1845
+ if( strlen($cff_link_desc_color_html) > 1 || strlen($cff_link_desc_size_html) > 1 ) $cff_link_desc_styles_html .= '"';
1846
+
1847
+ //Add links and create HTML
1848
+ $cff_link_description = '<span class="cff-post-desc" '.$cff_link_desc_styles_html.'>';
1849
+ if ($cff_title_link) {
1850
+ $cff_link_description .= cff_wrap_span( htmlspecialchars($description_text) );
1851
+ } else {
1852
+ $description_text = cff_autolink( htmlspecialchars($description_text), $link_color=$cff_posttext_link_color );
1853
+ //Replace line breaks with <br> tags
1854
+ $cff_link_description .= nl2br($description_text);
1855
+ }
1856
+ $cff_link_description .= ' </span>';
1857
 
 
 
 
 
 
 
 
 
 
 
1858
 
1859
+ if( $description_text != $cff_link_caption ) $cff_shared_link .= $cff_link_description;
1860
+ }
1861
 
1862
+ $cff_shared_link .= '</div></div>';
1863
  }
1864
 
1865
+ /* VIDEO */
 
1866
 
1867
+ //Check to see whether it's an embedded video so that we can show the name above the post text if necessary
1868
+ $cff_is_video_embed = false;
1869
+ if ( $cff_post_type == 'video' && isset($news->source) ){
1870
+ $url = $news->source;
1871
+ //Embeddable video strings
1872
+ $youtube = 'youtube';
1873
+ $youtu = 'youtu';
1874
+ $vimeo = 'vimeo';
1875
+ $youtubeembed = 'youtube.com/embed';
1876
+ //Check whether it's a youtube video
1877
+ $youtube = stripos($url, $youtube);
1878
+ $youtu = stripos($url, $youtu);
1879
+ $youtubeembed = stripos($url, $youtubeembed);
1880
+ //Check whether it's a youtube video
1881
+ if($youtube || $youtu || $youtubeembed || (stripos($url, $vimeo) !== false)) {
1882
+ $cff_is_video_embed = true;
1883
+ }
 
1884
  }
 
1885
 
1886
 
1887
+ $cff_media = '';
1888
+ if ($cff_post_type == 'video') {
1889
+ //Add the name to the description if it's a video embed
1890
+ if($cff_is_video_embed) {
1891
+ isset($news->name) ? $video_name = $news->name : $video_name = $link;
1892
+ isset($news->description) ? $description_text = $news->description : $description_text = '';
1893
+ //Add the 'cff-shared-link' class so that embedded videos display in a box
1894
+ $cff_description = '<div class="cff-desc-wrap cff-shared-link ';
1895
+ if (empty($picture)) $cff_description .= 'cff-no-image';
1896
+ if($cff_disable_link_box) $cff_description .= ' cff-no-styles"';
1897
+ if(!$cff_disable_link_box) $cff_description .= '" ' . $cff_link_box_styles;
1898
+ $cff_description .= '>';
1899
 
1900
+ if( isset($news->name) ) $cff_description .= '<'.$cff_link_title_format.' class="cff-link-title" '.$cff_link_title_styles.'><a href="'.$link.'" '.$target.$cff_nofollow.' style="color:#' . $cff_link_title_color . ';">'. $news->name . '</a></'.$cff_link_title_format.'>';
1901
 
1902
+ if (!empty($body_limit)) {
1903
+ if (strlen($description_text) > $body_limit) $description_text = substr($description_text, 0, $body_limit) . '...';
1904
+ }
1905
 
1906
+ $cff_description .= '<p class="cff-post-desc" '.$cff_body_styles.'><span>' . cff_autolink( htmlspecialchars($description_text) ) . '</span></p></div>';
1907
+ } else {
1908
+ isset($news->name) ? $video_name = $news->name : $video_name = $link;
1909
+ if( isset($news->name) ) $cff_description .= '<'.$cff_link_title_format.' class="cff-link-title" '.$cff_link_title_styles.'><a href="'.$link.'" '.$target.$cff_nofollow.' style="color:#' . $cff_link_title_color . ';">'. $news->name . '</a></'.$cff_link_title_format.'>';
1910
+ }
1911
  }
 
1912
 
1913
 
1914
+ //Display the link to the Facebook post or external link
1915
+ $cff_link = '';
1916
+ //Default link
1917
+ $cff_viewpost_class = 'cff-viewpost-facebook';
1918
+ if ($cff_facebook_link_text == '') $cff_facebook_link_text = 'View on Facebook';
1919
+ $link_text = $cff_facebook_link_text;
1920
 
1921
+ //Link to the Facebook post if it's a link or a video
1922
+ if($cff_post_type == 'link' || $cff_post_type == 'video') $link = "https://www.facebook.com/" . $page_id . "/posts/" . $PostID[1];
1923
 
1924
+ //Social media sharing URLs
1925
+ $cff_share_facebook = 'https://www.facebook.com/sharer/sharer.php?u=' . urlencode($link);
1926
+ $cff_share_twitter = 'https://twitter.com/intent/tweet?text=' . urlencode($link);
1927
+ $cff_share_google = 'https://plus.google.com/share?url=' . urlencode($link);
1928
+ $cff_share_linkedin = 'https://www.linkedin.com/shareArticle?mini=true&amp;url=' . urlencode($link) . '&amp;title=' . rawurlencode( strip_tags($cff_post_text) );
1929
+ $cff_share_email = 'mailto:?subject=Facebook&amp;body=' . urlencode($link) . '%20-%20' . rawurlencode( strip_tags($cff_post_text) );
1930
 
1931
+ //If it's a shared post then change the link to use the Post ID so that it links to the shared post and not the original post that's being shared
1932
+ if( isset($news->status_type) ){
1933
+ if( $news->status_type == 'shared_story' ) $link = "https://www.facebook.com/" . $cff_post_id;
1934
+ }
1935
 
1936
+ //If it's an offer post then change the text
1937
+ if ($cff_post_type == 'offer') $link_text = 'View Offer';
1938
 
1939
+ //Create post action links HTML
1940
+ $cff_link = '';
1941
+ if($cff_show_facebook_link || $cff_show_facebook_share){
1942
+ $cff_link .= '<div class="cff-post-links">';
1943
 
1944
+ //View on Facebook link
1945
+ if($cff_show_facebook_link) $cff_link .= '<a class="' . $cff_viewpost_class . '" href="' . $link . '" title="' . $link_text . '" ' . $target . $cff_nofollow . ' ' . $cff_link_styles . '>' . $link_text . '</a>';
1946
 
1947
+ //Share link
1948
+ if($cff_show_facebook_share){
1949
+ $cff_link .= '<div class="cff-share-container">';
1950
+ //Only show separating dot if both links are enabled
1951
+ if($cff_show_facebook_link) $cff_link .= '<span class="cff-dot" ' . $cff_link_styles . '>&middot;</span>';
1952
+ $cff_link .= '<a class="cff-share-link" href="'.$cff_share_facebook.'" title="' . $cff_facebook_share_text . '" ' . $cff_link_styles . '>' . $cff_facebook_share_text . '</a>';
1953
+ $cff_link .= "<p class='cff-share-tooltip'><a href='".$cff_share_facebook."' target='_blank' class='cff-facebook-icon'><span class='fa fab fa-facebook-square' aria-hidden='true'></span><span class='cff-screenreader'>Share on Facebook</span></a><a href='".$cff_share_twitter."' target='_blank' class='cff-twitter-icon'><span class='fa fab fa-twitter' aria-hidden='true'></span><span class='cff-screenreader'>Share on Twitter</span></a><a href='".$cff_share_linkedin."' target='_blank' class='cff-linkedin-icon'><span class='fa fab fa-linkedin' aria-hidden='true'></span><span class='cff-screenreader'>Share on Linked In</span></a><a href='".$cff_share_email."' target='_blank' class='cff-email-icon'><span class='fa fa-envelope' aria-hidden='true'></span><span class='cff-screenreader'>Share by Email</span></a><span class='fa fa-play fa-rotate-90' aria-hidden='true'></span></p></div>";
1954
+ }
1955
+
1956
+ $cff_link .= '</div>';
1957
  }
 
 
 
1958
 
1959
 
1960
+ /* MEDIA LINK */
1961
+ $cff_translate_photo_text = $atts['phototext'];
1962
+ if (!isset($cff_translate_photo_text) || empty($cff_translate_photo_text)) $cff_translate_photo_text = 'Photo';
1963
+ $cff_translate_video_text = $atts['videotext'];
1964
+ if (!isset($cff_translate_video_text) || empty($cff_translate_video_text)) $cff_translate_video_text = 'Video';
1965
 
1966
+ $cff_media_link = '';
1967
 
1968
+ if( $cff_show_media_link && ($cff_post_type == 'photo' || $cff_post_type == 'video' || $cff_album) ){
1969
+ $cff_media_link .= '<p class="cff-media-link"><a href="'.$link.'" '.$target.' style="color: #'.$cff_posttext_link_color.';"><span style="padding-right: 5px;" class="fa fas fa-';
1970
+ if($cff_post_type == 'photo' || $cff_album) $cff_media_link .= 'picture-o fa-image" aria-hidden="true"></span>'. $cff_translate_photo_text;
1971
+ // if($cff_post_type == 'video') $cff_media_link .= 'file-video-o';
1972
+ if($cff_post_type == 'video') $cff_media_link .= 'video-camera fa-video" aria-hidden="true"></span>'. $cff_translate_video_text;
1973
+ $cff_media_link .= '</a></p>';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1974
  }
1975
 
1976
+ //**************************//
1977
+ //***CREATE THE POST HTML***//
1978
+ //**************************//
1979
+ //Start the container
1980
+ $cff_post_item = '<div class="cff-item ';
1981
+ $cff_post_type_class = 'cff-status-post';
1982
+ if ($cff_post_type == 'link') $cff_post_type_class = 'cff-link-item';
1983
+ if ($cff_post_type == 'event') $cff_post_type_class = 'cff-timeline-event';
1984
+ if ($cff_post_type == 'photo') $cff_post_type_class = 'cff-photo-post';
1985
+ if ($cff_post_type == 'video') $cff_post_type_class = 'cff-video-post';
1986
+ if ($cff_post_type == 'swf') $cff_post_type_class = 'cff-swf-post';
1987
+ if ($cff_post_type == 'offer') $cff_post_type_class = 'cff-offer-post';
1988
+ $cff_post_item .= $cff_post_type_class;
1989
+ if ($cff_album) $cff_post_item .= ' cff-album';
1990
+
1991
+ if ($cff_post_bg_color_check || $cff_post_style == "boxed") $cff_post_item .= ' cff-box';
1992
+ if( $cff_box_shadow ) $cff_post_item .= ' cff-shadow';
1993
+ if(isset($news->from->name)) $cff_post_item .= ' author-'. cff_to_slug($news->from->name);
1994
+ $cff_post_item .= '" id="cff_'. $cff_post_id .'" ' . $cff_item_styles . '>';
1995
+
1996
+ //POST AUTHOR
1997
+ if($cff_show_author) $cff_post_item .= $cff_author;
1998
+ //DATE ABOVE
1999
+ if ($cff_show_date && $cff_date_position == 'above') $cff_post_item .= $cff_date;
2000
+ //POST TEXT
2001
+ if($cff_show_text || $cff_show_desc) $cff_post_item .= $cff_post_text;
2002
+ //LINK
2003
+ if($cff_show_shared_links) $cff_post_item .= $cff_shared_link;
2004
+ //DATE BELOW
2005
+ if ( (!$cff_show_author && $cff_date_position == 'author') || $cff_show_date && $cff_date_position == 'below') {
2006
+ if($cff_show_date && $cff_post_type !== 'event') $cff_post_item .= $cff_date;
2007
+ }
2008
+ //DATE BELOW (only for Event posts)
2009
+ if ( (!$cff_show_author && $cff_date_position == 'author') || $cff_show_date && $cff_date_position == 'below') {
2010
+ if($cff_show_date && $cff_post_type == 'event') $cff_post_item .= $cff_date;
2011
+ }
2012
+
2013
+ //MEDIA LINK
2014
+ if($cff_show_media_link) $cff_post_item .= $cff_media_link;
2015
+ //VIEW ON FACEBOOK LINK
2016
+ if($cff_show_link) $cff_post_item .= $cff_link;
2017
+
2018
+ //End the post item
2019
+ $cff_post_item .= '</div>';
2020
 
2021
+ //PUSH TO ARRAY
2022
+ $cff_posts_array = cff_array_push_assoc($cff_posts_array, $i_post, $cff_post_item);
2023
 
2024
+ } // End post type check
2025
 
2026
+ if (isset($news->message)) $prev_post_message = $news->message;
2027
+ if (isset($news->link)) $prev_post_link = $news->link;
2028
+ if (isset($news->description)) $prev_post_description = $news->description;
2029
 
2030
+ } // End the loop
2031
+ } //End isset($FBdata->data)
2032
 
2033
  //Sort the array in reverse order (newest first)
2034
  if(!$cff_is_group) ksort($cff_posts_array);
2107
 
2108
  return $cff_description_tagged;
2109
  }
2110
+ //Sort message tags by offset value
2111
+ function cffSortTags($a, $b) {
2112
+ return $a['offset'] - $b['offset'];
2113
+ }
2114
 
2115
  //Get JSON object of feed data
2116
  function cff_fetchUrl($url){
2117
  $response = wp_remote_get($url);
2118
  $feedData = wp_remote_retrieve_body( $response );
2119
+
2120
+ $feedData = apply_filters( 'cff_filter_api_data', $feedData );
2121
+
2122
  return $feedData;
2123
  }
2124
 
js/cff-admin-scripts.js CHANGED
@@ -216,14 +216,62 @@ jQuery(document).ready(function($) {
216
 
217
  $('#cff_token_expiration_note').show();
218
 
219
- $(this).siblings().removeClass('cff-page-selected');
220
- $(this).addClass('cff-page-selected');
 
 
 
 
221
  });
222
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
223
  //Insert Page Access Token
224
- $('#cff-insert-token').on('click', function(){
225
- $('#cff_access_token').val( $('.cff-page-selected').attr('data-token') ).addClass('cff-success');
226
- if( $('#cff_page_id').val().trim() == '' ) $('#cff_page_id').val( $('.cff-page-selected').attr('data-page-id') );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
227
 
228
  if( $(this).hasClass('cff-group-btn') ){
229
  $('.cff-groups-list').hide();
@@ -243,15 +291,330 @@ jQuery(document).ready(function($) {
243
  $('.cff-page-options').hide();
244
 
245
  //Dynamically create group edit link
246
- var cffGroupEditLink = 'https://facebook.com/groups/'+$('.cff-page-selected').attr('data-page-id')+'/edit';
247
  $('#cff-group-installation #cff-group-edit').attr('href', cffGroupEditLink);
248
  } else {
249
  $('.cff_modal_tokens').hide();
250
  }
251
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
252
  location.hash = "cffnomodal";
253
  });
254
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
255
  //Show the modal by default, but hide if the "cffnomodal" class is added to prevent it showing after saving settings
256
  if( location.hash !== '#cffnomodal' ){
257
  $('.cff_modal_tokens').removeClass('cffnomodal');
216
 
217
  $('#cff_token_expiration_note').show();
218
 
219
+ var $self = $(this);
220
+ if( $self.hasClass('cff-page-selected') ){
221
+ $self.removeClass('cff-page-selected');
222
+ } else {
223
+ $self.addClass('cff-page-selected');
224
+ }
225
  });
226
 
227
+
228
+
229
+
230
+
231
+ //Connect Accounts array object
232
+ var cff_connected_accounts = {},
233
+ cff_multifeed_enabled = false,
234
+ cff_remove_primary_text = 'Remove as Primary Feed',
235
+ cff_add_primary_text = 'Make Primary Feed';
236
+
237
+ if( $('#cff_page_id').hasClass('cff_multifeed_enabled') ) cff_multifeed_enabled = true;
238
+ if( cff_multifeed_enabled ){
239
+ cff_remove_primary_text = 'Remove from Primary Feed';
240
+ cff_add_primary_text = 'Add to Primary Feed';
241
+ }
242
+
243
+ //If there are accounts displayed then assign them to the connected accounts array
244
+ var cff_connected_accounts_val = $('#cff_connected_accounts').val();
245
+ if( cff_connected_accounts_val !== '' && cff_connected_accounts_val !== '{}' && typeof cff_connected_accounts_val !== 'undefined' ){
246
+
247
+ cff_connected_accounts = cff_connected_accounts_val.replace(/\\"/g, '"');
248
+ cff_connected_accounts = JSON.parse(cff_connected_accounts);
249
+
250
+ createAccountHTML(cff_connected_accounts);
251
+ }
252
+
253
  //Insert Page Access Token
254
+ $('#cff-insert-token, #cff-insert-all-tokens').on('click', function(){
255
+
256
+ if( $(this).hasClass('cff_connect_all') ) $('.cff-managed-page').addClass('cff-page-selected');
257
+
258
+ var $selectedPage = $('.cff-page-selected'),
259
+ selectedPageId = $selectedPage.attr('data-page-id'),
260
+ selectedPageToken = $selectedPage.attr('data-token');
261
+
262
+ //Add ID to setting
263
+ if( $('#cff_page_id').val().trim() == '' ){
264
+ $('#cff_page_id').val( selectedPageId ).addClass('cff-success');
265
+ cffAddCurIdLabel($('.cff-page-selected').first().find('.cff-page-info-name').text(), $('.cff-page-selected').first().find('.cff-page-avatar').attr('src'));
266
+ }
267
+
268
+ //Add token to setting
269
+ if( $('#cff_access_token').val().trim() == '' ){
270
+ //If multifeed then add ID to front so it's assigned to that ID in the feed
271
+ if( $('#cff_page_id').hasClass('cff_multifeed_enabled') ) selectedPageToken = selectedPageId + ':' + selectedPageToken;
272
+
273
+ $('#cff_access_token').val( selectedPageToken ).addClass('cff-success');
274
+ }
275
 
276
  if( $(this).hasClass('cff-group-btn') ){
277
  $('.cff-groups-list').hide();
291
  $('.cff-page-options').hide();
292
 
293
  //Dynamically create group edit link
294
+ var cffGroupEditLink = 'https://facebook.com/groups/'+selectedPageId+'/edit';
295
  $('#cff-group-installation #cff-group-edit').attr('href', cffGroupEditLink);
296
  } else {
297
  $('.cff_modal_tokens').hide();
298
  }
299
 
300
+ // cff_connected_accounts
301
+ $('.cff-managed-pages').find('.cff-page-selected').each(function(){
302
+ var $page = $(this);
303
+
304
+ addConnectedAccounts(
305
+ $page.attr('data-page-id'),
306
+ $page.find('.cff-page-info-name').text(),
307
+ $page.attr('data-pagetype'),
308
+ $page.attr('data-token'),
309
+ $page.find('.cff-page-avatar').attr('src')
310
+ );
311
+
312
+ });
313
+
314
  location.hash = "cffnomodal";
315
  });
316
 
317
+ //Manually connect account
318
+ //Step 1
319
+ $('#cff_manual_account_button').on('click', function(e){
320
+ e.preventDefault();
321
+ $('#cff_manual_account').toggle();
322
+ $('#cff_manual_account_step_1').show();
323
+ $('#cff_manual_account_step_2').hide();
324
+ });
325
+ //Step 2
326
+ jQuery("#cff_manual_account_type").change(function() {
327
+ $('#cff_manual_account_step_2').attr('class', 'cff_account_type_'+jQuery("#cff_manual_account_type option:selected").val() );
328
+
329
+ $('#cff_manual_account_step_1').hide();
330
+ $('#cff_manual_account_step_2').show();
331
+ });
332
+ //Add account
333
+ $('#cff_manual_account_step_2 input[type=submit').on('click', function(e){
334
+ e.preventDefault();
335
+
336
+ var $cff_manual_account = $('#cff_manual_account');
337
+
338
+ addConnectedAccounts(
339
+ $cff_manual_account.find('#cff_manual_account_id').val(),
340
+ $cff_manual_account.find('#cff_manual_account_name').val(),
341
+ $cff_manual_account.find('#cff_manual_account_type').val(),
342
+ $cff_manual_account.find('#cff_manual_account_token').val(),
343
+ false
344
+ );
345
+ });
346
+
347
+ //Only enable manual account submit button if ID/token fields have values
348
+ $('#cff_manual_account_id, #cff_manual_account_token').on('input', function() {
349
+ if( $('#cff_manual_account_id').val() == '' || $('#cff_manual_account_token').val() == '' ){
350
+ $('#cff_manual_account_step_2 #submit').attr('disabled', true);
351
+ } else {
352
+ $('#cff_manual_account_step_2 #submit').removeAttr('disabled');
353
+ }
354
+ });
355
+
356
+ //Show raw account data (can be used for exporting/importing accounts in bulk)
357
+ $('#cff_export_accounts').on('click', function(e){
358
+ e.preventDefault();
359
+ $('#cff_export_accounts_wrap').toggle();
360
+ });
361
+
362
+
363
+ function addConnectedAccounts(id, name, pagetype, accesstoken, avatar=false){
364
+
365
+ if( pagetype == 'page' ) avatar = '';
366
+
367
+ //Add to connected accounts array
368
+ cff_connected_accounts[id] = {
369
+ id: id,
370
+ name: encodeURI( name ),
371
+ pagetype: pagetype,
372
+ accesstoken: accesstoken,
373
+ avatar: avatar
374
+ };
375
+
376
+ //Update setting on page
377
+ $('#cff_connected_accounts').val( JSON.stringify(cff_connected_accounts) );
378
+
379
+ //Add HTML to page
380
+ createAccountHTML(cff_connected_accounts);
381
+ }
382
+
383
+ function removeConnectedAccount($account){
384
+ //Remove account from array
385
+ delete cff_connected_accounts[$account.attr('data-page-id')];
386
+
387
+ //Update setting on page
388
+ $('#cff_connected_accounts').val( JSON.stringify(cff_connected_accounts) );
389
+
390
+ //Remove it from primary feed if it's in there
391
+ removePrimaryAcount($account);
392
+
393
+ //Remove account element from page
394
+ $account.remove();
395
+ }
396
+
397
+ function createAccountHTML(cff_connected_accounts){
398
+
399
+ var accountsHTML = '';
400
+
401
+ //Loop through accounts and create HTML
402
+ for (var key in cff_connected_accounts) {
403
+ if (cff_connected_accounts.hasOwnProperty(key)) {
404
+
405
+ var id = cff_connected_accounts[key]['id'],
406
+ name = decodeURI(cff_connected_accounts[key]['name']),
407
+ pagetype = cff_connected_accounts[key]['pagetype'],
408
+ accesstoken = cff_connected_accounts[key]['accesstoken'],
409
+ avatar = cff_connected_accounts[key]['avatar'],
410
+ cff_account_active = '',
411
+ no_avatar = false;
412
+
413
+ if( (!avatar || avatar == 'false' ) && pagetype == 'group' ) no_avatar = true;
414
+ if( !avatar || avatar == '' ) avatar = 'https://graph.facebook.com/'+id+'/picture';
415
+
416
+ //If it's in use then mark it as primary/active
417
+ if( $('#cff_page_id').val().indexOf(id) !== -1 ) cff_account_active = ' cff_account_active';
418
+
419
+ accountsHTML += '<div class="cff_connected_account cff_account_type_'+pagetype+cff_account_active+'" id="cff_connected_account_'+id+'" data-accesstoken="'+accesstoken+'" data-pagetype="'+pagetype+'" data-page-id="'+id+'">' +
420
+ '<div class="cff_ca_info">' +
421
+ '<div class="cff_ca_delete"><a href="JavaScript:void(0);" class="cff_delete_account"><i class="fa fa-times"></i><span class="cff_remove_text">Remove</span></a></div>'+
422
+ '<div class="cff_ca_username">';
423
+ ( no_avatar ) ? accountsHTML += '' : accountsHTML += '<img class="cff_ca_avatar" src="'+avatar+'">';
424
+ accountsHTML += '<strong><span class="cff_ca_fullname">'+name+'</span><span class="cff_ca_pagetype">'+pagetype+' ID: '+id+'</span></strong>' +
425
+ '</div>' +
426
+ '<div class="cff_ca_actions">' +
427
+ '<a href="JavaScript:void(0);" class="cff_make_primary">';
428
+ if( cff_account_active !== '' ){
429
+ accountsHTML += '<i class="fa fa-minus-circle" aria-hidden="true"></i>'+cff_remove_primary_text;
430
+ } else {
431
+ accountsHTML += '<i class="fa fa-plus-circle" aria-hidden="true"></i>'+cff_add_primary_text;
432
+ }
433
+ accountsHTML += '</a>';
434
+
435
+ if( $('#cff_page_access_token').length && pagetype == 'page' ) accountsHTML += '<a href="JavaScript:void(0);" class="cff_make_reviews"><i class="fa fa-star" aria-hidden="true"></i>Use for Reviews Feed</a>';
436
+
437
+ accountsHTML += '<a class="cff_ca_token_shortcode" href="JavaScript:void(0);"><i class="fa fa-chevron-circle-right" aria-hidden="true"></i>Add to another Feed</a>' +
438
+ '<p class="cff_ca_show_token"><a href="javascript:void(0);" id="cff_ca_show_token_'+id+'"><i class="fa fa-ellipsis-h" style="margin: 0; font-size: 12px;" aria-hidden="true"></i></a></p>' +
439
+ '</div>' +
440
+ '<div class="cff_ca_shortcode">' +
441
+ '<p>Copy and paste this shortcode into your page or widget area:<br>' +
442
+ '<code>[custom-facebook-feed account="'+id+'"]</code>' +
443
+ '</p>';
444
+ if( cff_multifeed_enabled ) accountsHTML += '<p>To add multiple accounts in the same feed, simply separate them using commas:<br>' +
445
+ '<code>[custom-facebook-feed account="'+id+', account_2, account_3"]</code>' +
446
+ '</p>';
447
+ accountsHTML += '<p>Click <a href="https://smashballoon.com/custom-facebook-feed/docs/shortcodes/" target="_blank">here</a> to learn more about shortcodes</p>' +
448
+ '</div>' +
449
+ '<div class="cff_ca_accesstoken">' +
450
+ '<span class="cff_ca_token_label">Access Token:</span><input type="text" class="cff_ca_token" value="'+accesstoken+'" readonly="readonly" onclick="this.focus();this.select()" title="To copy, click the field then press Ctrl + C (PC) or Cmd + C (Mac).">' +
451
+ '</div>' +
452
+ '</div>' +
453
+ '</div>';
454
+ }
455
+ }
456
+
457
+ //Add HTML to page
458
+ $('#cff_connected_accounts_wrap').html(accountsHTML);
459
+
460
+ //Add Raw Data button
461
+ $('.cff_connected_actions').show();
462
+
463
+ }
464
+
465
+ function removePrimaryAcount($account){
466
+ //Remove ID/token from fields
467
+ if( $account.hasClass('cff_account_active') ){
468
+
469
+ var selected_id = $account.attr('data-page-id'),
470
+ selected_token = $account.attr('data-accesstoken');
471
+
472
+ //Remove as primary account
473
+ cffLabelAsPrimary($account);
474
+
475
+ $('#cff_primary_account_label').hide();
476
+
477
+ if( cff_multifeed_enabled ){
478
+
479
+ //Find the ID from the removed account and remove it from the ID field
480
+ var updatedIdVal = $('#cff_page_id').val().replace(selected_id, '');
481
+ //Remove any stray commas left over
482
+ updatedIdVal = updatedIdVal.replace(',,', '').replace(' ,', '').replace(/^, |, $/g,'');
483
+
484
+ $('#cff_page_id').val( updatedIdVal ).removeClass('cff-success');
485
+
486
+ //Remove Token
487
+ // var updatedTokenVal = $('#cff_access_token').val().replace(selected_id+':'+selected_token, '').replace(selected_token, '');
488
+ var updatedTokenVal = $('#cff_access_token').val().replace(selected_id+':'+selected_token, '');
489
+ //Remove any stray commas left over
490
+ updatedTokenVal = updatedTokenVal.replace(',,', '').replace(' ,', '').replace(':,', ':').replace(/^, |, $/g,'');
491
+
492
+ $('#cff_access_token').val( updatedTokenVal ).removeClass('cff-success');
493
+
494
+
495
+ } else {
496
+
497
+ //Revert ID/token fields back to previous values
498
+ $('#cff_page_id').val( $('#cff_page_id').attr('data-page-id') ).removeClass('cff-success');
499
+ $('#cff_access_token').val( $('#cff_access_token').attr('data-accesstoken') ).removeClass('cff-success');
500
+
501
+ }
502
+ }
503
+ }
504
+
505
+
506
+ var $body = $('body');
507
+ //Show Access Token
508
+ $body.on('click', '.cff_ca_show_token a', function(e) {
509
+ e.preventDefault();
510
+ jQuery(this).closest('.cff_ca_info').find('.cff_ca_accesstoken').slideToggle(200);
511
+ });
512
+ $body.on('click', '.cff_ca_token_shortcode, .cff_make_primary, .cff_make_reviews', function (event) {
513
+ event.preventDefault();
514
+ var $clicked = $(event.target);
515
+ //Show shortcode
516
+ if( $clicked.hasClass('cff_ca_token_shortcode') ) {
517
+ jQuery(this).closest('.cff_ca_info').find('.cff_ca_shortcode').slideToggle(200);
518
+ }
519
+ //Make Reviews account
520
+ if( $clicked.hasClass('cff_make_reviews') ){
521
+ $('#cff_page_access_token').val( $clicked.closest('.cff_connected_account').attr('data-accesstoken') ).addClass('cff-success');
522
+ }
523
+ //Make primary account
524
+ if( $clicked.hasClass('cff_make_primary') ){
525
+ var $selected_account = $clicked.closest('.cff_connected_account'),
526
+ selected_id = $selected_account.attr('data-page-id'),
527
+ selected_token = $selected_account.attr('data-accesstoken');
528
+
529
+
530
+ //Remove ID/token from fields
531
+ if( $selected_account.hasClass('cff_account_active') ){
532
+
533
+ removePrimaryAcount($selected_account);
534
+
535
+ //Add ID/token to fields
536
+ } else {
537
+
538
+ //Add as primary account
539
+ cffLabelAsPrimary($selected_account, true);
540
+
541
+ //Add ID/token to fields
542
+ if( cff_multifeed_enabled ){
543
+
544
+ //Add ID to existing IDs already in field
545
+ var id_sep = ', ',
546
+ existing_id = $('#cff_page_id').val().trim(),
547
+ existing_token = $('#cff_access_token').val().trim();
548
+
549
+ if( existing_id == '' ) id_sep = '';
550
+ $('#cff_page_id').val( existing_id + id_sep + selected_id ).addClass('cff-success');
551
+
552
+ //Change to multiple token format
553
+ var token_format = '';
554
+ if( existing_token !== '' ) token_format += existing_token + ', ';
555
+ token_format += selected_id + ':' + selected_token;
556
+
557
+ $('#cff_access_token').val( token_format ).addClass('cff-success');
558
+
559
+ } else {
560
+
561
+ //Replace existing ID and token
562
+ $('#cff_page_id').val( selected_id ).addClass('cff-success');
563
+ $('#cff_access_token').val( selected_token ).addClass('cff-success');
564
+
565
+ //Remove active account class from other accounts
566
+ $selected_account.siblings().each(function(){
567
+ cffLabelAsPrimary($(this));
568
+ });
569
+
570
+ }
571
+
572
+
573
+ }
574
+ }
575
+ });
576
+ //Remove account
577
+ $body.on('click', '.cff_delete_account', function(){
578
+ removeConnectedAccount( $(this).closest('.cff_connected_account') );
579
+ });
580
+
581
+ //Change button label when adding/removing as primary account
582
+ function cffLabelAsPrimary($account, makePrimary=false){
583
+ if( makePrimary ){
584
+ $account.addClass('cff_account_active').find('.cff_make_primary').html('<i class="fa fa-minus-circle" aria-hidden="true"></i>'+cff_remove_primary_text);
585
+
586
+ if( $account.length > 0 ) cffAddCurIdLabel($account.find('.cff_ca_fullname').text(), $account.find('.cff_ca_avatar').attr('src'));
587
+
588
+ } else {
589
+ $account.removeClass('cff_account_active').find('.cff_make_primary').html('<i class="fa fa-plus-circle" aria-hidden="true"></i>'+cff_add_primary_text);
590
+ }
591
+ }
592
+
593
+ function cffAddCurIdLabel(name, avatar){
594
+ var account_img = '',
595
+ account_name = '<span>' + name + '</span>';
596
+ if( avatar !== undefined ) account_img = '<img src="' + avatar + '" />';
597
+
598
+ $('#cff_primary_account_label').show().html( account_img + account_name );
599
+ }
600
+
601
+ //Label a primary account when page is first loaded
602
+ var cff_current_page_id = $('#cff_page_id').val(),
603
+ cff_current_page_id_arr = [];
604
+ if( typeof cff_current_page_id !== 'undefined' ) var cff_current_page_id_arr = cff_current_page_id.split(',');
605
+
606
+ if( cff_current_page_id_arr.length > 1 ){
607
+ for (var i = 0; i < cff_current_page_id_arr.length; i++) {
608
+ cffLabelAsPrimary( $('#cff_connected_account_' + cff_current_page_id_arr[i].trim() ), true );
609
+ }
610
+ } else {
611
+ cffLabelAsPrimary( $('#cff_connected_account_' + cff_current_page_id ), true );
612
+ }
613
+
614
+
615
+
616
+
617
+
618
  //Show the modal by default, but hide if the "cffnomodal" class is added to prevent it showing after saving settings
619
  if( location.hash !== '#cffnomodal' ){
620
  $('.cff_modal_tokens').removeClass('cffnomodal');