Business Profile - Version 1.1

Version Description

This major update adds support for multiple locations, refactors the codebase to follow WP coding guidelines, and adds several templates and helper functions for customization.

Download this release

Release Info

Developer NateWr
Plugin Icon 128x128 Business Profile
Version 1.1
Comparing to
See all releases

Code changes from version 1.0.9 to 1.1

assets/.esformatter ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "plugins": [
3
+ "esformatter-wordpress"
4
+ ],
5
+ "whiteSpace": {
6
+ "before": {
7
+ "AssignmentOperator": -1,
8
+ "PropertyValue": -1
9
+ },
10
+ "after": {
11
+ "VariableName": -1
12
+ }
13
+ }
14
+ }
assets/.jscsrc ADDED
@@ -0,0 +1,165 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "requireSpacesInConditionalExpression": {
3
+ "afterTest": true,
4
+ "beforeConsequent": true,
5
+ "afterConsequent": true,
6
+ "beforeAlternate": true
7
+ },
8
+ "requireSpacesInFunction": {
9
+ "beforeOpeningCurlyBrace": true
10
+ },
11
+ "disallowSpacesInAnonymousFunctionExpression": {
12
+ "beforeOpeningRoundBrace": true
13
+ },
14
+ "requireMultipleVarDecl": "onevar",
15
+ "requireSpacesInsideObjectBrackets": "all",
16
+ "disallowSpaceAfterObjectKeys": true,
17
+ "requireSpaceAfterBinaryOperators": [
18
+ "=", "+=", "-=", "*=", "/=", "%=", "<<=", ">>=", ">>>=",
19
+ "&=", "|=", "^=", "+=",
20
+
21
+ "+", "-", "*", "/", "%", "<<", ">>", ">>>", "&",
22
+ "|", "^", "&&", "||", "===", "==", ">=",
23
+ "<=", "<", ">", "!=", "!=="
24
+ ],
25
+ "requireSpaceBeforeBinaryOperators": [
26
+ "=", "+=", "-=", "*=", "/=", "%=", "<<=", ">>=", ">>>=",
27
+ "&=", "|=", "^=", "+=",
28
+
29
+ "+", "-", "*", "/", "%", "<<", ">>", ">>>", "&",
30
+ "|", "^", "&&", "||", "===", "==", ">=",
31
+ "<=", "<", ">", "!=", "!=="
32
+ ],
33
+ "disallowKeywords": ["with"],
34
+ "disallowMultipleLineBreaks": true,
35
+ "validateLineBreaks": "LF",
36
+ "disallowMixedSpacesAndTabs": "smart",
37
+ "disallowTrailingWhitespace": true,
38
+ "requireCurlyBraces": [
39
+ "if",
40
+ "else",
41
+ "for",
42
+ "while",
43
+ "do",
44
+ "try",
45
+ "catch"
46
+ ],
47
+ "requireSpaceBeforeBlockStatements": true,
48
+ "requireParenthesesAroundIIFE": true,
49
+ "requireBlocksOnNewline": true,
50
+ "requireOperatorBeforeLineBreak": [
51
+ "?",
52
+ "=",
53
+ "+",
54
+ "-",
55
+ "/",
56
+ "*",
57
+ "==",
58
+ "===",
59
+ "!=",
60
+ "!==",
61
+ ">",
62
+ ">=",
63
+ "<",
64
+ "<="
65
+ ],
66
+ "requireSpaceBeforeBinaryOperators": [
67
+ "?",
68
+ "=",
69
+ "+",
70
+ "-",
71
+ "/",
72
+ "*",
73
+ "==",
74
+ "===",
75
+ "!=",
76
+ "!==",
77
+ ">",
78
+ ">=",
79
+ "<",
80
+ "<="
81
+ ],
82
+ "requireSpaceAfterBinaryOperators": [
83
+ "?",
84
+ "=",
85
+ "+",
86
+ "/",
87
+ "*",
88
+ ":",
89
+ "==",
90
+ "===",
91
+ "!=",
92
+ "!==",
93
+ ">",
94
+ ">=",
95
+ "<",
96
+ "<="
97
+ ],
98
+ "disallowSpaceBeforeBinaryOperators": [","],
99
+ "disallowSpaceAfterBinaryOperators": [],
100
+ "disallowSpaceAfterPrefixUnaryOperators": ["++", "--", "+", "-", "~"],
101
+ "requireSpaceAfterPrefixUnaryOperators": ["!"],
102
+ "disallowSpaceBeforePostfixUnaryOperators": ["++", "--"],
103
+ "requireCamelCaseOrUpperCaseIdentifiers": true,
104
+ "disallowMultipleLineStrings": true,
105
+ "validateQuoteMarks": "'",
106
+ "validateIndentation": "\t",
107
+ "requireLineFeedAtFileEnd": true,
108
+ "requireDotNotation": true,
109
+ "disallowNewlineBeforeBlockStatements": true,
110
+ "requireSpaceAfterKeywords": [
111
+ "do",
112
+ "for",
113
+ "if",
114
+ "else",
115
+ "switch",
116
+ "case",
117
+ "try",
118
+ "catch",
119
+ "void",
120
+ "while",
121
+ "with",
122
+ "return",
123
+ "typeof"
124
+ ],
125
+ "requireSpaceAfterLineComment": true,
126
+ "requireSpaceBeforeKeywords": [
127
+ "else",
128
+ "while",
129
+ "catch"
130
+ ],
131
+ "requireSpaceBeforeObjectValues": true,
132
+ "requireSpaceBetweenArguments": true,
133
+ "requireSpacesInAnonymousFunctionExpression": {
134
+ "beforeOpeningCurlyBrace": true
135
+ },
136
+ "requireSpacesInForStatement": true,
137
+ "requireSpacesInsideArrayBrackets": "all",
138
+ "requireSpacesInsideParentheses": {
139
+ "all": true,
140
+ "except": [
141
+ "{",
142
+ "}",
143
+ "[",
144
+ "]",
145
+ "function"
146
+ ]
147
+ },
148
+ "requireYodaConditions": true,
149
+ "validateParameterSeparator": ", ",
150
+
151
+ "disallowTrailingComma": true,
152
+ "disallowPaddingNewlinesInBlocks": true,
153
+ "disallowEmptyBlocks": true,
154
+ "disallowQuotedKeysInObjects": "allButReserved",
155
+ "disallowDanglingUnderscores": true,
156
+ "requireCommaBeforeLineBreak": true,
157
+ "disallowKeywordsOnNewLine": ["else"],
158
+ "requireCapitalizedConstructors": true,
159
+ "safeContextKeyword": [ "that" ],
160
+ "jsDoc": {
161
+ "checkParamNames": true,
162
+ "checkRedundantParams": true,
163
+ "requireParamTypes": true
164
+ }
165
+ }
assets/.jshintrc ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "boss": true,
3
+ "curly": true,
4
+ "eqeqeq": true,
5
+ "eqnull": true,
6
+ "es3": true,
7
+ "expr": true,
8
+ "immed": true,
9
+ "noarg": true,
10
+ "onevar": true,
11
+ "quotmark": "single",
12
+ "trailing": true,
13
+ "undef": true,
14
+ "unused": true,
15
+
16
+ "browser": true,
17
+
18
+ "globals": {
19
+ "_": false,
20
+ "Backbone": false,
21
+ "jQuery": false,
22
+ "JSON": false,
23
+ "wp": false
24
+ }
25
+ }
assets/css/admin.css ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* Admin CSS styles for Business Profile */
2
+ .bpfwp-meta-input {
3
+ padding-top: 1em;
4
+ }
5
+
6
+ .bpfwp-meta-input textarea,
7
+ .bpfwp-meta-input select,
8
+ .bpfwp-meta-input input[type="text"],
9
+ .bpfwp-meta-input input[type="email"],
10
+ .bpfwp-meta-input input[type="tel"] {
11
+ width: 100%;
12
+ }
13
+
14
+ .bpfwp-meta-input textarea {
15
+ height: 8em;
16
+ }
17
+
18
+ .bpfwp-meta-geo_address,
19
+ .sap-coords-result {
20
+ margin: 0 -1em;
21
+ padding: 1em;
22
+ border-bottom: 1px solid #eee;
23
+ }
24
+
25
+ .sap-coords-result {
26
+ padding: 0.25em 1em;
27
+ }
28
+
29
+ .sap-coords-result .dashicons {
30
+ color: #aaa;
31
+ }
32
+
33
+ .bpfwp-meta-opening-hours .sap-scheduler-rule {
34
+ border: 1px solid #eee;
35
+ }
assets/css/contact-card.css CHANGED
@@ -107,4 +107,4 @@
107
  .bp-opening-hours-brief:before,
108
  .bp-opening-hours .bp-title:before {
109
  content: "\f469";
110
- }
107
  .bp-opening-hours-brief:before,
108
  .bp-opening-hours .bp-title:before {
109
  content: "\f469";
110
+ }
assets/js/map.js CHANGED
@@ -1,82 +1,108 @@
1
- /* Frontend Javascript for Business Profile maps */
2
- var bpfwp_map = bpfwp_map || {};
3
-
4
- jQuery(document).ready(function ($) {
5
-
6
- // Allow developers to override the maps api loading and initializing
7
- if ( !bpfwp_map.autoload_google_maps ) {
8
- return;
9
- }
10
-
11
- // Load Google Maps API and initialize maps
12
- if ( typeof google === 'undefined' || typeof google.maps === 'undefined' ) {
13
- var bp_map_script = document.createElement( 'script' );
14
- bp_map_script.type = 'text/javascript';
15
- bp_map_script.src = '//maps.googleapis.com/maps/api/js?v=3.exp&callback=bp_initialize_map';
16
- document.body.appendChild( bp_map_script );
17
 
18
- // If the API is already loaded (eg - by a third-party theme or plugin),
19
- // just initialize the map
20
- } else {
21
- bp_initialize_map();
22
- }
23
 
24
- });
25
-
26
- function bp_initialize_map() {
 
 
 
 
 
 
27
 
28
  bpfwp_map.maps = [];
29
  bpfwp_map.info_windows = [];
30
 
31
  jQuery( '.bp-map' ).each( function() {
32
- var id = jQuery(this).attr( 'id' );
33
- var data = jQuery(this).data();
 
 
34
 
35
  // Google Maps API v3
36
- if ( typeof data.lat !== 'undefined' ) {
37
- bpfwp_map.map_options = bpfwp_map.map_options || {};
 
38
  bpfwp_map.map_options.center = new google.maps.LatLng( data.lat, data.lon );
39
  if ( typeof bpfwp_map.map_options.zoom === 'undefined' ) {
40
  bpfwp_map.map_options.zoom = bpfwp_map.map_options.zoom || 15;
41
  }
42
-
43
  bpfwp_map.maps[ id ] = new google.maps.Map( document.getElementById( id ), bpfwp_map.map_options );
44
 
45
- var content = '<div class="bp-map-info-window">' +
46
- '<p><strong>' + data.name + '</strong></p>' +
47
- '<p>' + data.address.replace(/(?:\r\n|\r|\n)/g, '<br>') + '</p>';
48
 
49
- if ( typeof data.phone !== 'undefined' ) {
50
  content += '<p>' + data.phone + '</p>';
51
  }
52
- content += '<p><a target="_blank" href="//maps.google.com/maps?saddr=current+location&daddr=' + encodeURIComponent( data.address ) + '">Get Directions</a></p>' +
53
- '</div>';
54
 
55
  bpfwp_map.info_windows[ id ] = new google.maps.InfoWindow({
56
  position: bpfwp_map.map_options.center,
57
- content: content,
58
  });
59
- bpfwp_map.info_windows[ id ].open( bpfwp_map.maps[ id ]);
60
 
61
  // Trigger an intiailized event on this dom element for third-party code
62
- jQuery(this).trigger( 'bpfwp.map_initialized', [ id, bpfwp_map.maps[id], bpfwp_map.info_windows[id] ] );
63
 
64
  // Google Maps iframe embed (fallback if no lat/lon data available)
65
- } else if ( typeof data.address !== '' ) {
66
- var bp_map_iframe = document.createElement( 'iframe' );
67
- bp_map_iframe.frameBorder = 0;
68
- bp_map_iframe.style.width = '100%';
69
- bp_map_iframe.style.height = '100%';
 
70
 
71
- if ( typeof data.name !== '' ) {
72
  data.address = data.name + ',' + data.address;
73
  }
74
- bp_map_iframe.src = '//maps.google.com/maps?output=embed&q=' + encodeURIComponent( data.address );
75
 
76
- jQuery(this).html( bp_map_iframe );
 
 
 
77
 
78
  // Trigger an intiailized event on this dom element for third-party code
79
- jQuery(this).trigger( 'bpfwp.map_initialized_in_iframe', [ jQuery(this) ] );
80
  }
81
  });
82
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* global google */
2
+ /**
3
+ * Front-end JavaScript for Business Profile maps
4
+ *
5
+ * @copyright Copyright (c) 2016, Theme of the Crop
6
+ * @license GPL-2.0+
7
+ * @since 0.0.1
8
+ */
 
 
 
 
 
 
 
 
9
 
10
+ var bpfwp_map = bpfwp_map || {};
 
 
 
 
11
 
12
+ /**
13
+ * Set up a map using the Google Maps API and data attributes added to `.bp-map`
14
+ * elements on a given page.
15
+ *
16
+ * @uses Google Maps API (https://developers.google.com/maps/web/)
17
+ * @since 1.1.0
18
+ */
19
+ function bpInitializeMap() {
20
+ 'use strict';
21
 
22
  bpfwp_map.maps = [];
23
  bpfwp_map.info_windows = [];
24
 
25
  jQuery( '.bp-map' ).each( function() {
26
+ var id = jQuery( this ).attr( 'id' );
27
+ var data = jQuery( this ).data();
28
+
29
+ data.addressURI = encodeURIComponent( data.address.replace( /(<([^>]+)>)/ig, ', ' ) );
30
 
31
  // Google Maps API v3
32
+ if ( 'undefined' !== typeof data.lat ) {
33
+ data.addressURI = encodeURIComponent( data.address.replace( /(<([^>]+)>)/ig, ', ' ) );
34
+ bpfwp_map.map_options = bpfwp_map.map_options || {};
35
  bpfwp_map.map_options.center = new google.maps.LatLng( data.lat, data.lon );
36
  if ( typeof bpfwp_map.map_options.zoom === 'undefined' ) {
37
  bpfwp_map.map_options.zoom = bpfwp_map.map_options.zoom || 15;
38
  }
 
39
  bpfwp_map.maps[ id ] = new google.maps.Map( document.getElementById( id ), bpfwp_map.map_options );
40
 
41
+ var content = '<div class="bp-map-info-window">' + '<p><strong>' + data.name + '</strong></p>' + '<p>' + data.address.replace( /(?:\r\n|\r|\n)/g, '<br>' ) + '</p>';
 
 
42
 
43
+ if ( 'undefined' !== typeof data.phone ) {
44
  content += '<p>' + data.phone + '</p>';
45
  }
46
+
47
+ content += '<p><a target="_blank" href="//maps.google.com/maps?saddr=current+location&daddr=' + data.addressURI + '">' + bpfwp_map.strings.getDirections + '</a></p>' + '</div>';
48
 
49
  bpfwp_map.info_windows[ id ] = new google.maps.InfoWindow({
50
  position: bpfwp_map.map_options.center,
51
+ content: content
52
  });
53
+ bpfwp_map.info_windows[ id ].open( bpfwp_map.maps[ id ] );
54
 
55
  // Trigger an intiailized event on this dom element for third-party code
56
+ jQuery( this ).trigger( 'bpfwp.map_initialized', [ id, bpfwp_map.maps[id], bpfwp_map.info_windows[id] ] );
57
 
58
  // Google Maps iframe embed (fallback if no lat/lon data available)
59
+ } else if ( '' !== data.address ) {
60
+ var bpMapIframe = document.createElement( 'iframe' );
61
+
62
+ bpMapIframe.frameBorder = 0;
63
+ bpMapIframe.style.width = '100%';
64
+ bpMapIframe.style.height = '100%';
65
 
66
+ if ( '' !== data.name ) {
67
  data.address = data.name + ',' + data.address;
68
  }
 
69
 
70
+ bpMapIframe.src = '//maps.google.com/maps?output=embed&q=' + encodeURIComponent( data.address );
71
+ bpMapIframe.src = '//maps.google.com/maps?output=embed&q=' + data.addressURI;
72
+
73
+ jQuery( this ).html( bpMapIframe );
74
 
75
  // Trigger an intiailized event on this dom element for third-party code
76
+ jQuery( this ).trigger( 'bpfwp.map_initialized_in_iframe', [ jQuery( this ) ] );
77
  }
78
  });
79
  }
80
+
81
+ /**
82
+ * Backwards-compatable alias function.
83
+ *
84
+ * @since 1.1.0
85
+ */
86
+ function bp_initialize_map() {
87
+ bpInitializeMap();
88
+ }
89
+
90
+ jQuery( document ).ready( function() {
91
+ 'use strict';
92
+
93
+ // Allow developers to override the maps api loading and initializing.
94
+ if ( ! bpfwp_map.autoload_google_maps ) {
95
+ return;
96
+ }
97
+ // Load Google Maps API and initialize maps.
98
+ if ( 'undefined' === typeof google || 'undefined' === typeof google.maps ) {
99
+ var bpMapScript = document.createElement( 'script' );
100
+ bpMapScript.type = 'text/javascript';
101
+ bpMapScript.src = '//maps.googleapis.com/maps/api/js?v=3.exp&callback=bp_initialize_map';
102
+ document.body.appendChild( bpMapScript );
103
+ } else {
104
+ // If the API is already loaded (eg - by a third-party theme or plugin),
105
+ // just initialize the map.
106
+ bp_initialize_map();
107
+ }
108
+ });
business-profile.php CHANGED
@@ -1,121 +1,278 @@
1
- <?php
2
- /**
3
- * Plugin Name: Business Profile
4
- * Plugin URI: http://themeofthecrop.com
5
- * Description: Contact information, Google Maps and opening hours made easy for businesses.
6
- * Version: 1.0.9
7
- * Author: Theme of the Crop
8
- * Author URI: http://themeofthecrop.com
9
- * License: GNU General Public License v2.0 or later
10
- * License URI: http://www.gnu.org/licenses/gpl-2.0.html
11
- *
12
- * Text Domain: bpfwpdomain
13
- * Domain Path: /languages/
14
- *
15
- * This program is free software; you can redistribute it and/or modify it under the terms of the GNU
16
- * General Public License as published by the Free Software Foundation; either version 2 of the License,
17
- * or (at your option) any later version.
18
- *
19
- * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
20
- * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
21
- *
22
- * You should have received a copy of the GNU General Public License along with this program; if not, write
23
- * to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24
- */
25
- if ( ! defined( 'ABSPATH' ) )
26
- exit;
27
-
28
- if ( !class_exists( 'bpfwpInit' ) ) {
29
- class bpfwpInit {
30
-
31
- /**
32
- * Settings for displaying the contact card currently being handled
33
- * @since 0.0.1
34
- */
35
- public $display_settings = array();
36
-
37
- /**
38
- * Initialize the plugin and register hooks
39
- */
40
- public function __construct() {
41
-
42
- // Common strings
43
- define( 'BPFWP_PLUGIN_DIR', untrailingslashit( plugin_dir_path( __FILE__ ) ) );
44
- define( 'BPFWP_PLUGIN_URL', untrailingslashit( plugins_url( basename( plugin_dir_path( __FILE__ ) ), basename( __FILE__ ) ) ) );
45
- define( 'BPFWP_PLUGIN_FNAME', plugin_basename( __FILE__ ) );
46
- define( 'BPFWP_VERSION', 1 );
47
-
48
- // Load the textdomain
49
- add_action( 'init', array( $this, 'load_textdomain' ) );
50
-
51
- // Load settings
52
- require_once( BPFWP_PLUGIN_DIR . '/includes/Settings.class.php' );
53
- $this->settings = new bpfwpSettings();
54
-
55
- // Load the template functions which print the contact cards
56
- require_once( BPFWP_PLUGIN_DIR . '/includes/template-functions.php' );
57
-
58
- // Load integrations with third-party plugins/apps
59
- require_once( BPFWP_PLUGIN_DIR . '/includes/Integrations.class.php' );
60
-
61
- // Load assets
62
- add_action( 'wp_enqueue_scripts', array( $this, 'register_assets' ) );
63
-
64
- // Register the widget
65
- add_action( 'widgets_init', array( $this, 'register_widgets' ) );
66
-
67
- // Add links to plugin listing
68
- add_filter('plugin_action_links', array( $this, 'plugin_action_links' ), 10, 2);
69
-
70
- // Load backwards compatibility functions
71
- require_once( BPFWP_PLUGIN_DIR . '/includes/Compatibility.class.php' );
72
- new bpfwpCompatibility();
73
-
74
- }
75
-
76
- /**
77
- * Load the plugin textdomain for localistion
78
- * @since 0.0.1
79
- */
80
- public function load_textdomain() {
81
- load_plugin_textdomain( 'business-profile', false, plugin_basename( dirname( __FILE__ ) ) . "/languages/" );
82
- }
83
-
84
- /**
85
- * Register the front-end CSS styles
86
- * @since 0.0.1
87
- */
88
- function register_assets() {
89
- wp_register_style( 'bpfwp-default', BPFWP_PLUGIN_URL . '/assets/css/contact-card.css' );
90
- wp_register_script( 'bpfwp-map', BPFWP_PLUGIN_URL . '/assets/js/map.js' );
91
- }
92
-
93
- /**
94
- * Register the widgets
95
- * @since 0.0.1
96
- */
97
- public function register_widgets() {
98
- require_once( BPFWP_PLUGIN_DIR . '/includes/WP_Widget.ContactCardWidget.class.php' );
99
- register_widget( 'bpfwpContactCardWidget' );
100
- }
101
-
102
- /**
103
- * Add links to the plugin listing on the installed plugins page
104
- * @since 0.0.1
105
- */
106
- public function plugin_action_links( $links, $plugin ) {
107
-
108
- if ( $plugin == BPFWP_PLUGIN_FNAME ) {
109
-
110
- $links['help'] = '<a href="' . BPFWP_PLUGIN_URL . '/docs" title="' . __( 'View the help documentation for Business Profile', 'business-profile' ) . '">' . __( 'Help', 'business-profile' ) . '</a>';
111
- }
112
-
113
- return $links;
114
-
115
- }
116
-
117
- }
118
- } // endif;
119
-
120
- global $bpfwp_controller;
121
- $bpfwp_controller = new bpfwpInit();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Plugin Name: Business Profile
4
+ * Plugin URI: http://themeofthecrop.com
5
+ * Description: Contact information, Google Maps and opening hours made easy for businesses.
6
+ * Version: 1.1
7
+ * Author: Theme of the Crop
8
+ * Author URI: http://themeofthecrop.com
9
+ * License: GNU General Public License v2.0 or later
10
+ * License URI: http://www.gnu.org/licenses/gpl-2.0.html
11
+ *
12
+ * Text Domain: business-profile
13
+ * Domain Path: /languages/
14
+ *
15
+ * This program is free software; you can redistribute it and/or modify it under the terms of the GNU
16
+ * General Public License as published by the Free Software Foundation; either version 2 of the License,
17
+ * or (at your option) any later version.
18
+ *
19
+ * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
20
+ * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
21
+ *
22
+ * You should have received a copy of the GNU General Public License along with this program; if not, write
23
+ * to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24
+ *
25
+ * @package BusinessProfile
26
+ * @copyright Copyright (c) 2016, Theme of the Crop
27
+ * @license GPL-2.0+
28
+ * @since 0.0.1
29
+ */
30
+
31
+ defined( 'ABSPATH' ) || exit;
32
+
33
+ if ( ! class_exists( 'bpfwpInit', false ) ) :
34
+
35
+ class bpfwpInit {
36
+
37
+ /**
38
+ * Settings for displaying the contact card currently being handled.
39
+ *
40
+ * @since 0.0.1
41
+ * @access public
42
+ * @var array
43
+ */
44
+ public $display_settings = array();
45
+
46
+ /**
47
+ * Placeholder for the main settings class instance.
48
+ *
49
+ * @since 0.0.1
50
+ * @access public
51
+ * @var object bpfwpSettings
52
+ */
53
+ public $settings;
54
+
55
+ /**
56
+ * Placeholder for the main CPTs class instance.
57
+ *
58
+ * @since 0.0.1
59
+ * @access public
60
+ * @var object bpfwpCustomPostTypes
61
+ */
62
+ public $cpts;
63
+
64
+ /**
65
+ * Initialize the plugin and register hooks.
66
+ *
67
+ * @since 0.0.1
68
+ * @access public
69
+ * @return void
70
+ */
71
+ public function __construct() {
72
+ self::constants();
73
+ self::includes();
74
+ self::instantiate();
75
+ self::wp_hooks();
76
+ if ( $this->settings->get_setting( 'multiple-locations' ) ) {
77
+ register_activation_hook( __FILE__, array( $this->cpts, 'flush_rewrite_rules' ) );
78
+ }
79
+ }
80
+
81
+ /**
82
+ * Define plugin constants.
83
+ *
84
+ * @since 1.1.0
85
+ * @access protected
86
+ * @return void
87
+ */
88
+ protected function constants() {
89
+ define( 'BPFWP_PLUGIN_DIR', untrailingslashit( plugin_dir_path( __FILE__ ) ) );
90
+ define( 'BPFWP_PLUGIN_URL', untrailingslashit( plugin_dir_url( __FILE__ ) ) );
91
+ define( 'BPFWP_PLUGIN_FNAME', plugin_basename( __FILE__ ) );
92
+ define( 'BPFWP_VERSION', '1.1' );
93
+ }
94
+
95
+ /**
96
+ * Include all plugin files.
97
+ *
98
+ * @since 1.1.0
99
+ * @access protected
100
+ * @return void
101
+ */
102
+ protected function includes() {
103
+ require_once BPFWP_PLUGIN_DIR . '/includes/class-compatibility.php';
104
+ require_once BPFWP_PLUGIN_DIR . '/includes/class-custom-post-types.php';
105
+ require_once BPFWP_PLUGIN_DIR . '/includes/deprecated/class-integrations.php';
106
+ require_once BPFWP_PLUGIN_DIR . '/includes/class-settings.php';
107
+ require_once BPFWP_PLUGIN_DIR . '/includes/class-template-loader.php';
108
+ require_once BPFWP_PLUGIN_DIR . '/includes/template-functions.php';
109
+ }
110
+
111
+ /**
112
+ * Spin up instances of our plugin classes.
113
+ *
114
+ * @since 1.1.0
115
+ * @access protected
116
+ * @return void
117
+ */
118
+ protected function instantiate() {
119
+ new bpfwpCompatibility();
120
+ new bpfwpIntegrations(); // Deprecated in v1.1.
121
+ $this->settings = new bpfwpSettings();
122
+ if ( $this->settings->get_setting( 'multiple-locations' ) ) {
123
+ $this->cpts = new bpfwpCustomPostTypes();
124
+ $this->cpts->run();
125
+ }
126
+ }
127
+
128
+ /**
129
+ * Hook into WordPress.
130
+ *
131
+ * @since 1.1.0
132
+ * @access protected
133
+ * @return void
134
+ */
135
+ protected function wp_hooks() {
136
+ add_action( 'init', array( $this, 'load_textdomain' ) );
137
+ add_action( 'wp_enqueue_scripts', array( $this, 'register_assets' ) );
138
+ add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_admin_assets' ) );
139
+ add_action( 'widgets_init', array( $this, 'register_widgets' ) );
140
+ add_filter( 'plugin_action_links', array( $this, 'plugin_action_links' ), 10, 2 );
141
+ }
142
+
143
+ /**
144
+ * Load the plugin textdomain for localistion.
145
+ *
146
+ * @since 0.0.1
147
+ * @access public
148
+ * @return void
149
+ */
150
+ public function load_textdomain() {
151
+ load_plugin_textdomain(
152
+ 'business-profile',
153
+ false,
154
+ plugin_basename( dirname( __FILE__ ) ) . '/languages'
155
+ );
156
+ }
157
+
158
+ /**
159
+ * Register the front-end CSS styles
160
+ *
161
+ * @since 0.0.1
162
+ * @access public
163
+ * @return void
164
+ */
165
+ function register_assets() {
166
+ wp_register_style(
167
+ 'bpfwp-default',
168
+ BPFWP_PLUGIN_URL . '/assets/css/contact-card.css',
169
+ null,
170
+ BPFWP_VERSION
171
+ );
172
+ wp_register_script(
173
+ 'bpfwp-map',
174
+ BPFWP_PLUGIN_URL . '/assets/js/map.js',
175
+ array( 'jquery' ),
176
+ BPFWP_VERSION,
177
+ true
178
+ );
179
+ }
180
+
181
+ /**
182
+ * Register the widgets
183
+ *
184
+ * @since 0.0.1
185
+ * @access public
186
+ * @return void
187
+ */
188
+ public function register_widgets() {
189
+ require_once BPFWP_PLUGIN_DIR . '/includes/class-contact-card-widget.php';
190
+ register_widget( 'bpfwpContactCardWidget' );
191
+ }
192
+
193
+ /**
194
+ * Enqueue the admin CSS for locations
195
+ *
196
+ * @since 1.1
197
+ * @access public
198
+ * @global WP_Post $post The current WordPress post object.
199
+ * @param string $hook_suffix The current admin screen slug.
200
+ * @return void
201
+ */
202
+ public function enqueue_admin_assets( $hook_suffix ) {
203
+
204
+ global $post;
205
+
206
+ if ( 'post-new.php' === $hook_suffix || 'post.php' === $hook_suffix ) {
207
+ if ( $this->cpts->location_cpt_slug === $post->post_type ) {
208
+ wp_enqueue_style( 'bpfwp-admin-location', BPFWP_PLUGIN_URL . '/assets/css/admin.css' );
209
+ }
210
+ }
211
+ }
212
+
213
+ /**
214
+ * Add links to the plugin listing on the installed plugins page
215
+ *
216
+ * @since 0.0.1
217
+ * @access public
218
+ * @param array $links The current plugin action links.
219
+ * @param string $plugin The current plugin slug.
220
+ * @return array $links Modified action links.
221
+ */
222
+ public function plugin_action_links( $links, $plugin ) {
223
+ if ( BPFWP_PLUGIN_FNAME === $plugin ) {
224
+ $links['help'] = sprintf( '<a href="%s/docs" title="%s">%s</a>',
225
+ BPFWP_PLUGIN_URL,
226
+ __( 'View the help documentation for Business Profile', 'business-profile' ),
227
+ __( 'Help', 'business-profile' )
228
+ );
229
+ }
230
+
231
+ return $links;
232
+ }
233
+
234
+ /**
235
+ * Retrieve the get_theme_supports() value for a feature
236
+ *
237
+ * @since 1.1
238
+ * @access public
239
+ * @param string $feature A theme support feature to get.
240
+ * @return bool Whether or not a feature is supported.
241
+ */
242
+ public function get_theme_support( $feature ) {
243
+
244
+ $theme_support = get_theme_support( 'business-profile' );
245
+
246
+ if ( true === $theme_support ) {
247
+ return true;
248
+ } elseif ( false === $theme_support ) {
249
+ return false;
250
+ } else {
251
+ $theme_support = (array) $theme_support;
252
+ $theme_support = array_shift( $theme_support );
253
+ return isset( $theme_support[ $feature ] ) && true === $theme_support[ $feature ];
254
+ }
255
+ }
256
+
257
+ /**
258
+ * Return a single instance of the main plugin class.
259
+ *
260
+ * Developers and tests may still create multiple instances by spinning
261
+ * them up directly, but for most uses, this method is preferred.
262
+ *
263
+ * @since 1.1.0
264
+ * @access public
265
+ * @static
266
+ * @return object bpfwpInit A single instance of the main plugin class.
267
+ */
268
+ public static function instance() {
269
+ static $instance;
270
+ if ( null === $instance ) {
271
+ $instance = new self;
272
+ }
273
+ return $instance;
274
+ }
275
+ }
276
+ endif;
277
+
278
+ $bpfwp_controller = bpfwpInit::instance();
docs/index.html DELETED
@@ -1,141 +0,0 @@
1
- <!DOCTYPE html>
2
- <html lang="en-US">
3
- <head>
4
-
5
- <meta charset="UTF-8">
6
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
7
- <title>Business Profile | How to install and use this plugin</title>
8
- <link rel="profile" href="http://gmpg.org/xfn/11">
9
- <meta name="robots" content="noindex,nofollow">
10
- <link rel="stylesheet" href="style.css" type="text/css" media="all" />
11
-
12
- </head>
13
-
14
- <body>
15
-
16
- <div id="toc">
17
- <ul>
18
- <li>
19
- <a href="#install">Installation</a>
20
- </li>
21
- <li>
22
- <a href="#setup">Quick Setup</a>
23
- </li>
24
- <li>
25
- <a href="#shortcode">Shortcode</a>
26
- </li>
27
- <li>
28
- <a href="#extend">Extend this plugin</a>
29
- </li>
30
- </ul>
31
- </div>
32
-
33
- <div id="content">
34
-
35
- <h1>Guide to the Business Profile plugin for WordPress</h1>
36
- <p>This guide will help you install and configure the plugin for your site.</p>
37
- <p>Further support for this plugin can be found at <a href="http://themeofthecrop.com/?utm_source=Plugin&utm_medium=Plugin%20Help%20Documentation&utm_campaign=Business%Profile">themeofthecrop.com</a>.</p>
38
-
39
- <a name="install"></a>
40
- <h2>Installation</h2>
41
- <p>The following steps describe how to upload the Business Profile plugin to an
42
- existing WordPress installation. If you have not yet installed WordPress, consult the
43
- <a href="http://codex.wordpress.org/Installing_WordPress">WordPress
44
- documentation</a> for more information.</p>
45
- <ol>
46
- <li>
47
- Unpack the business-profile.zip file. It should create a folder
48
- named <code>/business-profile/</code>.
49
- </li>
50
- <li>
51
- Upload the <code>/business-profile/</code> folder to your
52
- WordPress plugin directory at <code>/wp-content/plugins/</code>.
53
- </li>
54
- <li>
55
- Go to your WordPress admin dashboard at yoursite.com/wp-admin and
56
- click the <strong>Plugins</strong> item in the menu on the left.
57
- </li>
58
- <li>
59
- Find <strong>Business Profile</strong> in the list of Plugins
60
- and click the <strong>Activate</strong> link below the plugin name.
61
- </li>
62
- </ol>
63
- <p>The plugin is now active. Next you'll need to get it setup.</p>
64
-
65
- <a name="setup"></a>
66
- <h2>Quick Setup</h2>
67
- <p>To get this plugin working as quickly as possible, all you need to do is
68
- fill out your business details and add the widget</p>
69
- <ol>
70
- <li>
71
- Go to the <strong>Business Profile</strong> page in your admin
72
- dashboard. It should appear near the bottom of the menu on the left.
73
- </li>
74
- <li>
75
- Fill out your business details on this page and click the Save
76
- button at the bottom.
77
- </li>
78
- <li>
79
- Simply paste <code>[contact-card]</code> into the content of any
80
- page or post. Or add the new Contact Card widget to any sidebar.
81
- </li>
82
- </ol>
83
- <p>Once you've done that, your users can view your business details. Read
84
- the <a href="#shortcode">Shortcode</a> section to learn about customizing
85
- what details are displayed.</p>
86
-
87
- <a name="shortcode"></a>
88
- <h2>Shortcode</h2>
89
- <p>Prints the contact details to your site. All details will be displayed with the default shortcode <code>[contact-card]</code>. To hide any of the components, set the attribute to 0.</p>
90
- <p><code>[contact-card show_name=1 show_address=1 show_get_directions=1 show_phone=1 show_contact=1 show_opening_hours=1 show_opening_hours_brief=0 show_map=1]</code></p>
91
- <ul>
92
- <li>
93
- <strong>show_name</strong><br>
94
- Whether or not to show the name of the business.
95
- </li>
96
- <li>
97
- <strong>show_address</strong><br>
98
- Whether or not to show the address.
99
- </li>
100
- <li>
101
- <strong>show_get_directions</strong><br>
102
- Whether or not to show a link to Google Maps with directions from the user's current location to your address.
103
- </li>
104
- <li>
105
- <strong>show_phone</strong><br>
106
- Whether or not to show your phone number.
107
- </li>
108
- <li>
109
- <strong>show_contact</strong><br>
110
- Whether or not to show a link to your contact page if set. Otherwise it will show the email address if one has been added to the Business Profile settings page.
111
- </li>
112
- <li>
113
- <strong>show_opening_hours</strong><br>
114
- Whether or not to show your opening hours.
115
- </li>
116
- <li>
117
- <strong>show_opening_hours_brief</strong><br>
118
- Whether or not to show a short, one-line version of your opening hours. This is turned off by default. Set it to 1 to turn it on.
119
- </li>
120
- <li>
121
- <strong>show_map</strong><br>
122
- Whether or not to show a Google Map with your location.
123
- </li>
124
- </ul>
125
-
126
- <a name="extend"></a>
127
- <h2>Extend this plugin</h2>
128
- <p>This plugin has been designed from the ground up to be extensible and
129
- customizable. There are several hooks to allow you to customize the
130
- functionality and output.</p>
131
- <p>If you have any questions, please
132
- <a href="http://themeofthecrop.com/about/support/?utm_source=Plugin&utm_medium=Plugin%20Help%20Documentation&utm_campaign=Business%Profile">contact me</a>.</p>
133
- <p>This plugin is available on
134
- <a href="https://github.com/NateWr/business-profile">GitHub</a>
135
- if you would like to contribute pull requests.</p>
136
-
137
- </div>
138
-
139
- </body>
140
-
141
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
docs/style.css DELETED
@@ -1,31 +0,0 @@
1
- /**
2
- * Documentation Markup
3
- **********************/
4
- body {
5
- font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
6
- background-color: #eee;
7
- margin: 0;
8
- }
9
- li {
10
- padding-bottom: 5px;
11
- }
12
- #toc {
13
- position: absolute;
14
- width: 250px;
15
- }
16
- #content {
17
- padding: 20px;
18
- margin-left: 300px;
19
- background-color: #fff;
20
- box-shadow: 0 0 5px #000;
21
- }
22
- #toc>ul>li {
23
- padding-bottom: 10px;
24
- padding-top: 10px;
25
- }
26
- code {
27
- font-family: Courier, monospace;
28
- padding: 2px 5px;
29
- background-color: #eee;
30
- border-radius: 2px;
31
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/Integrations.class.php DELETED
@@ -1,140 +0,0 @@
1
- <?php
2
- /**
3
- * Initialize third-party integrations
4
- *
5
- * This file loads and runs code to help the theme that can be found in
6
- * wp-content/themes/plate-up/includes. This code is separated from the normal
7
- * functions.php file to make that file easier to read. Ideally, all code that
8
- * is typically customized by users will be accessible through functions.php.
9
- * The code that is loaded here should only pertain to more advanced features
10
- * and functions that few users will ever touch if they are using this theme.
11
- */
12
- if ( ! defined( 'ABSPATH' ) )
13
- exit;
14
-
15
- if ( !class_exists( 'bpfwpIntegrations' ) ) {
16
- class bpfwpIntegrations {
17
-
18
- public function __construct() {
19
-
20
- add_action( 'plugins_loaded', array( $this, 'plugins_loaded' ) );
21
-
22
- }
23
-
24
- /**
25
- * Integrations run after the plugins are loaded
26
- * @since 0.0.1
27
- */
28
- public function plugins_loaded() {
29
-
30
- // Restaurant Reservations plugin
31
- if ( defined( 'RTB_PLUGIN_DIR' ) ) {
32
-
33
- // Add default setting for booking link to template function/shortcode
34
- add_filter( 'bpwfp_contact_card_defaults', array( $this, 'bpwfp_booking_link_default' ) );
35
-
36
- // Add the callback to print the booking link
37
- add_filter( 'bpwfwp_component_callbacks', array( $this, 'bpwfp_booking_link_callback' ) );
38
-
39
- // Add display toggle for the booking link to the widget options
40
- add_filter( 'bpfwp_widget_display_toggles', array( $this, 'bpfwp_booking_link_widget_option' ) );
41
-
42
- }
43
- }
44
-
45
- /**
46
- * Add default setting for booking link to template function/shortcode
47
- * Restaurant Reservations plugin
48
- * @since 0.0.1
49
- */
50
- public function bpwfp_booking_link_default( $defaults ) {
51
-
52
- $defaults['show_booking_link'] = true;
53
-
54
- return $defaults;
55
- }
56
-
57
- /**
58
- * Add the callback to print the booking link
59
- * Restaurant Reservations plugin
60
- * @since 0.0.1
61
- */
62
- public function bpwfp_booking_link_callback( $data ) {
63
-
64
- global $rtb_controller;
65
- $booking_page = $rtb_controller->settings->get_setting( 'booking-page' );
66
-
67
- if ( !empty( $booking_page ) ) {
68
-
69
- // Place the link at the end of other short links if they're
70
- // displayed
71
- if ( isset( $data['contact'] ) ) {
72
- $pos = array_search( 'contact', array_keys( $data ) );
73
- } elseif ( isset( $data['phone'] ) ) {
74
- $pos = array_search( 'phone', array_keys( $data ) );
75
- } elseif ( isset( $data['address'] ) ) {
76
- $pos = array_search( 'address', array_keys( $data ) );
77
- }
78
-
79
- if ( !empty( $pos ) ) {
80
- $a = array_slice( $data, 0, $pos );
81
- $b = array_slice( $data, $pos );
82
- $data = array_merge( $a, array( 'booking_page' => array( $this, 'bpfwp_print_booking_link' ) ) , $b );
83
-
84
- // If no short links are being displayed, just add it to the bottom.
85
- } else {
86
- $data['booking_page'] = array( $this, 'bpfwp_print_booking_link' );
87
- }
88
- }
89
-
90
- return $data;
91
- }
92
-
93
- /**
94
- * Print the booking link
95
- * Restaurant Reservations plugin
96
- * @since 0.0.1
97
- */
98
- public function bpfwp_print_booking_link() {
99
-
100
- global $bpfwp_controller;
101
-
102
- if ( $bpfwp_controller->display_settings['show_booking_link'] ) :
103
- global $rtb_controller;
104
- ?>
105
-
106
- <div class="bp-booking">
107
- <a href="<?php echo get_permalink( $rtb_controller->settings->get_setting( 'booking-page' ) ); ?>"><?php _e( 'Book a table', 'business-profile' ); ?></a>
108
- </div>
109
-
110
- <?php
111
- endif;
112
- }
113
-
114
- /**
115
- * Add the booking page display option to the widget options
116
- * Restaurant Reservations plugin
117
- * @since 0.0.1
118
- */
119
- public function bpfwp_booking_link_widget_option( $toggles ) {
120
-
121
- // Place the option below the contact option
122
- $pos = array_search( 'show_contact', array_keys( $toggles ) );
123
-
124
- if ( !empty( $pos ) ) {
125
- $a = array_slice( $toggles, 0, $pos );
126
- $b = array_slice( $toggles, $pos );
127
- $toggles = array_merge( $a, array( 'show_booking_link' => __( 'Show book a table link', 'business-profile' ) ) , $b );
128
-
129
- // If no short links are being displayed, just add it to the bottom.
130
- } else {
131
- $toggles['show_booking_link'] = __( 'Show book a table link', 'business-profile' );
132
- }
133
-
134
- return $toggles;
135
- }
136
-
137
- }
138
- } // endif;
139
-
140
- new bpfwpIntegrations();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/Settings.class.php DELETED
@@ -1,316 +0,0 @@
1
- <?php
2
- if ( !defined( 'ABSPATH' ) ) exit;
3
-
4
- if ( !class_exists( 'bpfwpSettings' ) ) {
5
- /**
6
- * Class to handle configurable settings for Business Profile
7
- *
8
- * @since 0.0.1
9
- */
10
- class bpfwpSettings {
11
-
12
- /**
13
- * Default values for settings
14
- * @since 0.0.1
15
- */
16
- public $defaults = array();
17
-
18
- /**
19
- * Stored values for settings
20
- * @since 0.0.1
21
- */
22
- public $settings = array();
23
-
24
- public function __construct() {
25
-
26
- add_action( 'init', array( $this, 'set_defaults' ) );
27
-
28
- add_action( 'init', array( $this, 'load_settings_panel' ) );
29
-
30
- }
31
-
32
- /**
33
- * Load the plugin's default settings
34
- * @since 0.0.1
35
- */
36
- public function set_defaults() {
37
-
38
- $this->defaults = array(
39
- 'schema_type' => 'Organization',
40
- 'name' => get_bloginfo( 'name' ),
41
- );
42
-
43
- $this->defaults = apply_filters( 'bpfwp_defaults', $this->defaults );
44
- }
45
-
46
- /**
47
- * Get a setting's value or fallback to a default if one exists
48
- * @since 0.0.1
49
- */
50
- public function get_setting( $setting ) {
51
-
52
- if ( empty( $this->settings ) ) {
53
- $this->settings = get_option( 'bpfwp-settings' );
54
- }
55
-
56
- if ( !empty( $this->settings[ $setting ] ) ) {
57
- return $this->settings[ $setting ];
58
- }
59
-
60
- if ( !empty( $this->defaults[ $setting ] ) ) {
61
- return $this->defaults[ $setting ];
62
- }
63
-
64
- return null;
65
- }
66
-
67
- /**
68
- * Load the admin settings page
69
- * @since 0.0.1
70
- * @sa https://github.com/NateWr/simple-admin-pages
71
- */
72
- public function load_settings_panel() {
73
-
74
- require_once( BPFWP_PLUGIN_DIR . '/lib/simple-admin-pages/simple-admin-pages.php' );
75
- $sap = sap_initialize_library(
76
- $args = array(
77
- 'version' => '2.0',
78
- 'lib_url' => BPFWP_PLUGIN_URL . '/lib/simple-admin-pages/',
79
- )
80
- );
81
-
82
- $sap->add_page(
83
- 'menu',
84
- array(
85
- 'id' => 'bpfwp-settings',
86
- 'title' => __( 'Business Profile', 'business-profile' ),
87
- 'menu_title' => __( 'Business Profile', 'business-profile' ),
88
- 'capability' => 'manage_options',
89
- 'icon' => 'dashicons-businessman',
90
- 'position' => null
91
- )
92
- );
93
-
94
- $sap->add_section(
95
- 'bpfwp-settings',
96
- array(
97
- 'id' => 'bpfwp-seo',
98
- 'title' => __( 'Search Engine Optimization', 'business-profile' ),
99
- )
100
- );
101
-
102
- $sap->add_setting(
103
- 'bpfwp-settings',
104
- 'bpfwp-seo',
105
- 'select',
106
- array(
107
- 'id' => 'schema_type',
108
- 'title' => __( 'Schema Type', 'business-profile' ),
109
- 'description' => __( 'Select the option that best describes your business to improve how search engines understand your website', 'business-profile' ) . ' <a href="http://schema.org/" target="_blank">Schema.org</a>',
110
- 'blank_option' => false,
111
- 'options' => array(
112
- 'Organization' => 'Organization',
113
- 'Corporation' => 'Corporation',
114
- 'EducationalOrganization' => 'Educational Organization',
115
- 'GovernmentOrganization' => 'Government Organization',
116
- 'LocalBusiness' => 'Local Business',
117
- 'AnimalShelter' => '- Animal Shelter',
118
- 'AutomotiveBusiness' => '- Automotive Business',
119
- 'ChildCare' => '- Child Care',
120
- 'DryCleaningOrLaundry' => '- Dry Cleaning or Laundry',
121
- 'EmergencyService' => '- Emergency Service',
122
- 'EmploymentAgency' => '- Employment Agency',
123
- 'EntertainmentBusiness' => '- Entertainment Business',
124
- 'FinancialService' => '- Financial Service',
125
- 'FoodEstablishment' => '- Food Establishment',
126
- 'GovernmentOffice' => '- Government Office',
127
- 'HealthAndBeautyBusiness' => '- Health and Beauty Business',
128
- 'HomeAndConstructionBusiness' => '- Home and Construction Business',
129
- 'InternetCafe' => '- Internet Cafe',
130
- 'Library' => '- Library',
131
- 'LodgingBusiness' => '- Lodging Business',
132
- 'MedicalOrganization' => '- Medical Organization',
133
- 'RadioStation' => '- Radio Station',
134
- 'RealEstateAgent' => '- Real Estate Agent',
135
- 'RecyclingCenter' => '- Recycling Center',
136
- 'SelfStorage' => '- Self Storage',
137
- 'SportsActivityLocation' => '- Sports Activity Location',
138
- 'Store' => '- Store',
139
- 'TouristInformationCenter' => '- Tourist Information Center',
140
- 'TravelAgency' => '- Travel Agency',
141
- 'NGO' => 'NGO',
142
- 'PerformingGroup' => 'PerformingGroup',
143
- 'SportsTeam' => 'SportsTeam',
144
- ),
145
- )
146
- );
147
-
148
- $sap->add_section(
149
- 'bpfwp-settings',
150
- array(
151
- 'id' => 'bpfwp-contact',
152
- 'title' => __( 'Contact Information', 'business-profile' ),
153
- )
154
- );
155
-
156
- $sap->add_setting(
157
- 'bpfwp-settings',
158
- 'bpfwp-contact',
159
- 'text',
160
- array(
161
- 'id' => 'name',
162
- 'title' => __( 'Name', 'business-profile' ),
163
- 'description' => __( 'Enter the name of your business if it is different than the website name.', 'business-profile' ),
164
- 'placeholder' => $this->defaults['name'],
165
- )
166
- );
167
-
168
- $sap->add_setting(
169
- 'bpfwp-settings',
170
- 'bpfwp-contact',
171
- 'address',
172
- array(
173
- 'id' => 'address',
174
- 'title' => __( 'Address', 'business-profile' ),
175
- 'strings' => array(
176
- 'sep-action-links' => _x( ' | ', 'separator between admin action links in address component', 'business-profile' ),
177
- 'sep-lat-lon' => _x( ', ', 'separates latitude and longitude', 'business-profile' ),
178
- 'no-setting' => __( 'No map coordinates set.', 'business-profile' ),
179
- 'retrieving' => __( 'Requesting new coordinates', 'business-profile' ),
180
- 'select' => __( 'Select a match below', 'business-profile' ),
181
- 'view' => __( 'View', 'business-profile' ),
182
- 'retrieve' => __( 'Retrieve map coordinates', 'business-profile' ),
183
- 'remove' => __( 'Remove map coordinates', 'business-profile' ),
184
- 'try_again' => __( 'Try again?', 'business-profile' ),
185
- 'result_error' => __( 'Error', 'business-profile' ),
186
- 'result_invalid' => __( 'Invalid request. Be sure to fill out the address field before retrieving coordinates.', 'business-profile' ),
187
- 'result_denied' => __( 'Request denied.', 'business-profile' ),
188
- 'result_limit' => __( 'Request denied because you are over your request quota.', 'business-profile' ),
189
- 'result_empty' => __( 'Nothing was found at that address', 'business-profile' ),
190
- ),
191
- )
192
- );
193
-
194
- $sap->add_setting(
195
- 'bpfwp-settings',
196
- 'bpfwp-contact',
197
- 'text',
198
- array(
199
- 'id' => 'phone',
200
- 'title' => __( 'Phone', 'business-profile' ),
201
- )
202
- );
203
-
204
- $sap->add_setting(
205
- 'bpfwp-settings',
206
- 'bpfwp-contact',
207
- 'post',
208
- array(
209
- 'id' => 'contact-page',
210
- 'title' => __( 'Contact Page', 'business-profile' ),
211
- 'description' => __( 'Select a page on your site where users can reach you, such as a contact form.', 'business-profile' ),
212
- 'blank_option' => true,
213
- 'args' => array(
214
- 'post_type' => 'page',
215
- 'posts_per_page' => -1,
216
- 'post_status' => 'publish',
217
- ),
218
- )
219
- );
220
-
221
- $sap->add_setting(
222
- 'bpfwp-settings',
223
- 'bpfwp-contact',
224
- 'text',
225
- array(
226
- 'id' => 'contact-email',
227
- 'title' => __( 'Email Address (optional)', 'business-profile' ),
228
- 'description' => __( 'Enter an email address only if you want to display this publicly. Showing your email address on your site may cause you to receive excessive spam.', 'business-profile' ),
229
- )
230
- );
231
-
232
- $sap->add_section(
233
- 'bpfwp-settings',
234
- array(
235
- 'id' => 'bpfwp-schedule',
236
- 'title' => __( 'Schedule', 'business-profile' ),
237
- )
238
- );
239
-
240
- $sap->add_setting(
241
- 'bpfwp-settings',
242
- 'bpfwp-schedule',
243
- 'scheduler',
244
- array(
245
- 'id' => 'opening-hours',
246
- 'title' => __( 'Opening Hours', 'business-profile' ),
247
- 'description' => __( 'Define your weekly opening hours by adding scheduling rules.', 'business-profile' ),
248
- 'weekdays' => array(
249
- 'monday' => _x( 'Mo', 'Monday abbreviation', 'business-profile' ),
250
- 'tuesday' => _x( 'Tu', 'Tuesday abbreviation', 'business-profile' ),
251
- 'wednesday' => _x( 'We', 'Wednesday abbreviation', 'business-profile' ),
252
- 'thursday' => _x( 'Th', 'Thursday abbreviation', 'business-profile' ),
253
- 'friday' => _x( 'Fr', 'Friday abbreviation', 'business-profile' ),
254
- 'saturday' => _x( 'Sa', 'Saturday abbreviation', 'business-profile' ),
255
- 'sunday' => _x( 'Su', 'Sunday abbreviation', 'business-profile' )
256
- ),
257
- 'time_format' => _x( 'h:i A', 'Time format displayed in the opening hours setting panel in your admin area. Must match formatting rules at http://amsul.ca/pickadate.js/time.htm#formats', 'business-profile' ),
258
- 'date_format' => _x( 'mmmm d, yyyy', 'Date format displayed in the opening hours setting panel in your admin area. Must match formatting rules at http://amsul.ca/pickadate.js/date.htm#formatting-rules', 'business-profile' ),
259
- 'disable_weeks' => true,
260
- 'disable_date' => true,
261
- 'strings' => array(
262
- 'add_rule' => __( 'Add another opening time', 'business-profile' ),
263
- 'weekly' => _x( 'Weekly', 'Format of a scheduling rule', 'business-profile' ),
264
- 'monthly' => _x( 'Monthly', 'Format of a scheduling rule', 'business-profile' ),
265
- 'date' => _x( 'Date', 'Format of a scheduling rule', 'business-profile' ),
266
- 'weekdays' => _x( 'Days of the week', 'Label for selecting days of the week in a scheduling rule', 'business-profile' ),
267
- 'month_weeks' => _x( 'Weeks of the month', 'Label for selecting weeks of the month in a scheduling rule', 'business-profile' ),
268
- 'date_label' => _x( 'Date', 'Label to select a date for a scheduling rule', 'business-profile' ),
269
- 'time_label' => _x( 'Time', 'Label to select a time slot for a scheduling rule', 'business-profile' ),
270
- 'allday' => _x( 'All day', 'Label to set a scheduling rule to last all day', 'business-profile' ),
271
- 'start' => _x( 'Start', 'Label for the starting time of a scheduling rule', 'business-profile' ),
272
- 'end' => _x( 'End', 'Label for the ending time of a scheduling rule', 'business-profile' ),
273
- 'set_time_prompt' => _x( 'All day long. Want to %sset a time slot%s?', 'Prompt displayed when a scheduling rule is set without any time restrictions', 'business-profile' ),
274
- 'toggle' => _x( 'Open and close this rule', 'Toggle a scheduling rule open and closed', 'business-profile' ),
275
- 'delete' => _x( 'Delete rule', 'Delete a scheduling rule', 'business-profile' ),
276
- 'delete_schedule' => __( 'Delete scheduling rule', 'business-profile' ),
277
- 'never' => _x( 'Never', 'Brief default description of a scheduling rule when no weekdays or weeks are included in the rule', 'business-profile' ),
278
- 'weekly_always' => _x( 'Every day', 'Brief default description of a scheduling rule when all the weekdays/weeks are included in the rule', 'business-profile' ),
279
- 'monthly_weekdays' => _x( '%s on the %s week of the month', 'Brief default description of a scheduling rule when some weekdays are included on only some weeks of the month. %s should be left alone and will be replaced by a comma-separated list of days and weeks in the following format: M, T, W on the first, second week of the month', 'business-profile' ),
280
- 'monthly_weeks' => _x( '%s week of the month', 'Brief default description of a scheduling rule when some weeks of the month are included but all or no weekdays are selected. %s should be left alone and will be replaced by a comma-separated list of weeks in the following format: First, second week of the month', 'business-profile' ),
281
- 'all_day' => _x( 'All day', 'Brief default description of a scheduling rule when no times are set', 'business-profile' ),
282
- 'before' => _x( 'Ends at', 'Brief default description of a scheduling rule when an end time is set but no start time. If the end time is 6pm, it will read: Ends at 6pm', 'business-profile' ),
283
- 'after' => _x( 'Starts at', 'Brief default description of a scheduling rule when a start time is set but no end time. If the start time is 6pm, it will read: Starts at 6pm', 'business-profile' ),
284
- 'separator' => _x( '&mdash;', 'Separator between times of a scheduling rule', 'business-profile' ),
285
- ),
286
- )
287
- );
288
-
289
- $sap->add_section(
290
- 'bpfwp-settings',
291
- array(
292
- 'id' => 'bpfwp-display',
293
- 'title' => __( 'Display', 'business-profile' ),
294
- )
295
- );
296
-
297
- $sap->add_setting(
298
- 'bpfwp-settings',
299
- 'bpfwp-display',
300
- 'html',
301
- array(
302
- 'id' => 'shortcode',
303
- 'title' => __( 'Shortcode', 'business-profile' ),
304
- 'description' => '',
305
- 'html' => '<div><code>[contact-card]</code></div><p class="description">' . sprintf( __( 'Paste this shortcode into any page or post to display your contact details. Learn about %sall of the attributes%s in the documentation.', 'business-profile' ), '<a href="' . BPFWP_PLUGIN_URL . DIRECTORY_SEPARATOR . 'docs#shortcode">', '</a>' ) . ' </p>',
306
- )
307
- );
308
-
309
- $sap = apply_filters( 'bpfwp_settings_page', $sap );
310
-
311
- $sap->add_admin_menus();
312
-
313
- }
314
-
315
- }
316
- } // endif;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/WP_Widget.ContactCardWidget.class.php DELETED
@@ -1,118 +0,0 @@
1
- <?php
2
- if ( ! defined( 'ABSPATH' ) ) exit;
3
-
4
- if ( ! class_exists( 'WP_Widget' ) ) {
5
- require_once ABSPATH . 'wp-admin/includes/widgets.php';
6
- }
7
-
8
- if ( !class_exists( 'bpfwpContactCardWidget' ) ) {
9
- /**
10
- * Contact card widget
11
- *
12
- * Extends WP_Widget to display a contact card in a widget.
13
- * @since 0.0.1
14
- */
15
- class bpfwpContactCardWidget extends WP_Widget {
16
-
17
- /**
18
- * Register widget with WordPress.
19
- * @since 0.0.1
20
- */
21
- function __construct() {
22
-
23
- // Display toggles
24
- $this->toggles = apply_filters( 'bpfwp_widget_display_toggles', array(
25
- 'show_name' => __( 'Show Name', 'business-profile' ),
26
- 'show_address' => __( 'Show Address', 'business-profile' ),
27
- 'show_get_directions' => __( 'Show link to get directions on Google Maps', 'business-profile' ),
28
- 'show_phone' => __( 'Show Phone number', 'business-profile' ),
29
- 'show_contact' => __( 'Show contact details', 'business-profile' ),
30
- 'show_opening_hours' => __( 'Show Opening Hours', 'business-profile' ),
31
- 'show_opening_hours_brief' => __( 'Show brief opening hours on one line', 'business-profile' ),
32
- 'show_map' => __( 'Show Google Map', 'business-profile' ),
33
- )
34
- );
35
-
36
- parent::__construct(
37
- 'bpfwp_contact_card_widget',
38
- __('Contact Card', 'business-profile'),
39
- array( 'description' => __( 'Display a contact card with your name, address, phone number, opening hours and map.', 'business-profile' ), )
40
- );
41
-
42
- }
43
-
44
- /**
45
- * Print the widget content
46
- * @since 0.0.1
47
- */
48
- public function widget( $args, $instance ) {
49
-
50
- global $bpfwp_controller;
51
-
52
- // Print the widget's HTML markup
53
- echo $args['before_widget'];
54
- if( isset( $instance['title'] ) ) {
55
- $title = apply_filters( 'widget_title', $instance['title'] );
56
- echo $args['before_title'] . $title . $args['after_title'];
57
- }
58
-
59
- $shortcode_args = $instance;
60
- unset( $shortcode_args['title'] );
61
- unset( $shortcode_args['before_widget'] );
62
- unset( $shortcode_args['after_widget'] );
63
- unset( $shortcode_args['before_title'] );
64
- unset( $shortcode_args['after_title'] );
65
-
66
- $shortcode_atts = array();
67
- foreach( $shortcode_args as $key => $val ) {
68
- $value = empty( $val ) ? 0 : 1;
69
- $shortcode_atts[] = esc_attr( $key ) . '=' . $value;
70
- }
71
- echo do_shortcode( '[contact-card ' . join( ' ', $shortcode_atts ) . ']' );
72
-
73
- echo $args['after_widget'];
74
-
75
- }
76
-
77
- /**
78
- * Print the form to configure this widget in the admin panel
79
- * @since 1.0
80
- */
81
- public function form( $instance ) {
82
- ?>
83
-
84
- <p>
85
- <label for="<?php echo $this->get_field_id( 'title' ); ?>"> <?php _e( 'Title' ); ?></label>
86
- <input class="widefat" id="<?php echo $this->get_field_id( 'title' ); ?>" name="<?php echo $this->get_field_name( 'title' ); ?>" type="text"<?php if ( isset( $instance['title'] ) ) : ?> value="<?php echo esc_attr( $instance['title'] ); ?>"<?php endif; ?>>
87
- </p>
88
-
89
- <?php foreach( $this->toggles as $id => $label ) : ?>
90
-
91
- <p>
92
- <input type="checkbox" id="<?php echo $this->get_field_id( $id ); ?>" name="<?php echo $this->get_field_name( $id ); ?>" value="1"<?php if ( !empty( $instance[$id] ) ) : ?> checked="checked"<?php endif; ?>>
93
- <label for="<?php echo $this->get_field_id( $id ); ?>"> <?php echo $label; ?></label>
94
- </p>
95
-
96
- <?php endforeach;
97
- }
98
-
99
- /**
100
- * Sanitize and save the widget form values.
101
- * @since 1.0
102
- */
103
- public function update( $new_instance, $old_instance ) {
104
-
105
- $instance = array();
106
- if ( !empty( $new_instance['title'] ) ) {
107
- $instance['title'] = strip_tags( $new_instance['title'] );
108
- }
109
-
110
- foreach( $this->toggles as $id => $label ) {
111
- $instance[ $id ] = empty( $new_instance[ $id ] ) ? false : true;
112
- }
113
-
114
- return $instance;
115
- }
116
-
117
- }
118
- } // endif
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/{Compatibility.class.php → class-compatibility.php} RENAMED
@@ -1,9 +1,17 @@
1
  <?php
2
- if ( ! defined( 'ABSPATH' ) ) {
3
- exit;
4
- }
 
 
 
 
 
 
 
 
 
5
 
6
- if ( ! class_exists( 'bpfwpCompatibility', false ) ) {
7
  /**
8
  * Class to handle backwards compatibility issues for Business Profile.
9
  *
@@ -12,17 +20,23 @@ if ( ! class_exists( 'bpfwpCompatibility', false ) ) {
12
  class bpfwpCompatibility {
13
 
14
  /**
15
- * Set up hooks
 
 
 
 
16
  */
17
  public function __construct() {
18
-
19
  // Preserve this defined constant in case anyone relied on it
20
- // to check if the plugin was active
21
  define( 'BPFWP_TEXTDOMAIN', 'bpfwpdomain' );
22
 
23
- // Load a .mo file for an old textdomain if one exists
24
  add_filter( 'load_textdomain_mofile', array( $this, 'load_old_textdomain' ), 10, 2 );
25
 
 
 
 
26
  }
27
 
28
  /**
@@ -35,6 +49,12 @@ if ( ! class_exists( 'bpfwpCompatibility', false ) ) {
35
  * it does, so that people don't lose their translations.
36
  *
37
  * Old textdomain: bpfwpdomain
 
 
 
 
 
 
38
  */
39
  public function load_old_textdomain( $mofile, $textdomain ) {
40
  if ( 'business-profile' !== $textdomain ) {
@@ -48,5 +68,16 @@ if ( ! class_exists( 'bpfwpCompatibility', false ) ) {
48
  return $mofile;
49
  }
50
 
 
 
 
 
 
 
 
 
 
 
 
51
  }
52
- } // end class exists check.
1
  <?php
2
+ /**
3
+ * Provide backwards compatibility for older versions of Business Profile.
4
+ *
5
+ * @package BusinessProfile
6
+ * @copyright Copyright (c) 2016, Theme of the Crop
7
+ * @license GPL-2.0+
8
+ * @since 1.0.6
9
+ */
10
+
11
+ defined( 'ABSPATH' ) || exit;
12
+
13
+ if ( ! class_exists( 'bpfwpCompatibility', false ) ) :
14
 
 
15
  /**
16
  * Class to handle backwards compatibility issues for Business Profile.
17
  *
20
  class bpfwpCompatibility {
21
 
22
  /**
23
+ * Set up hooks.
24
+ *
25
+ * @since 1.0.6
26
+ * @access public
27
+ * @return void
28
  */
29
  public function __construct() {
 
30
  // Preserve this defined constant in case anyone relied on it
31
+ // to check if the plugin was active.
32
  define( 'BPFWP_TEXTDOMAIN', 'bpfwpdomain' );
33
 
34
+ // Load a .mo file for an old textdomain if one exists.
35
  add_filter( 'load_textdomain_mofile', array( $this, 'load_old_textdomain' ), 10, 2 );
36
 
37
+ // Run a filter that was renamed in version 1.1.
38
+ add_filter( 'bpfwp_default_display_settings', array( $this, 'run_contact_card_defaults' ) );
39
+
40
  }
41
 
42
  /**
49
  * it does, so that people don't lose their translations.
50
  *
51
  * Old textdomain: bpfwpdomain
52
+ *
53
+ * @since 1.0.6
54
+ * @access public
55
+ * @param string $mofile The path to the current mofile.
56
+ * @param string $textdomain The current textdomain.
57
+ * @return string $mofile The modified mofile.
58
  */
59
  public function load_old_textdomain( $mofile, $textdomain ) {
60
  if ( 'business-profile' !== $textdomain ) {
68
  return $mofile;
69
  }
70
 
71
+ /**
72
+ * Run a filter that was renamed in version 1.1
73
+ *
74
+ * @since 1.1
75
+ * @access public
76
+ * @param array $defaults The contact card defaults.
77
+ * @return array $defaults The filtered contact card defaults.
78
+ */
79
+ public function run_contact_card_defaults( $defaults ) {
80
+ return apply_filters( 'bpwfp_contact_card_defaults', $defaults );
81
+ }
82
  }
83
+ endif;
includes/class-contact-card-widget.php ADDED
@@ -0,0 +1,167 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The contact card widget class.
4
+ *
5
+ * @package BusinessProfile
6
+ * @copyright Copyright (c) 2016, Theme of the Crop
7
+ * @license GPL-2.0+
8
+ * @since 0.0.1
9
+ */
10
+
11
+ defined( 'ABSPATH' ) || exit;
12
+
13
+ if ( ! class_exists( 'WP_Widget', false ) ) {
14
+ require_once ABSPATH . 'wp-admin/includes/widgets.php';
15
+ }
16
+
17
+ if ( ! class_exists( 'bpfwpContactCardWidget', false ) ) :
18
+
19
+ /**
20
+ * Contact card widget
21
+ *
22
+ * Extends WP_Widget to display a contact card in a widget.
23
+ *
24
+ * @since 0.0.1
25
+ */
26
+ class bpfwpContactCardWidget extends WP_Widget {
27
+
28
+ /**
29
+ * Register widget with WordPress.
30
+ *
31
+ * @since 0.0.1
32
+ * @access public
33
+ * @return void
34
+ */
35
+ public function __construct() {
36
+
37
+ // Display toggles.
38
+ $this->toggles = apply_filters( 'bpfwp_widget_display_toggles', array(
39
+ 'show_name' => __( 'Show Name', 'business-profile' ),
40
+ 'show_address' => __( 'Show Address', 'business-profile' ),
41
+ 'show_get_directions' => __( 'Show link to get directions on Google Maps', 'business-profile' ),
42
+ 'show_phone' => __( 'Show Phone number', 'business-profile' ),
43
+ 'show_contact' => __( 'Show contact details', 'business-profile' ),
44
+ 'show_opening_hours' => __( 'Show Opening Hours', 'business-profile' ),
45
+ 'show_opening_hours_brief' => __( 'Show brief opening hours on one line', 'business-profile' ),
46
+ 'show_map' => __( 'Show Google Map', 'business-profile' ),
47
+ )
48
+ );
49
+
50
+ parent::__construct(
51
+ 'bpfwp_contact_card_widget',
52
+ __( 'Contact Card', 'business-profile' ),
53
+ array( 'description' => __( 'Display a contact card with your name, address, phone number, opening hours and map.', 'business-profile' ) )
54
+ );
55
+
56
+ }
57
+
58
+ /**
59
+ * Print the widget content
60
+ *
61
+ * @since 0.0.1
62
+ * @access public
63
+ * @param array $args Display arguments including before_title, after_title, before_widget, and after_widget.
64
+ * @param array $instance The settings for the particular instance of the widget.
65
+ * @return void
66
+ */
67
+ public function widget( $args, $instance ) {
68
+ echo $args['before_widget'];
69
+ if ( isset( $instance['title'] ) ) {
70
+ $title = apply_filters( 'widget_title', $instance['title'] );
71
+ echo $args['before_title'] . $title . $args['after_title'];
72
+ }
73
+ echo bpwfwp_print_contact_card( $instance );
74
+ echo $args['after_widget'];
75
+ }
76
+
77
+ /**
78
+ * Print the form to configure this widget in the admin panel.
79
+ *
80
+ * @since 1.0
81
+ * @access public
82
+ * @global object $bpfwp_controller BPFWP controller class instance.
83
+ * @param array $instance Current widget settings.
84
+ * @return void
85
+ */
86
+ public function form( $instance ) {
87
+ global $bpfwp_controller;
88
+ ?>
89
+
90
+ <p>
91
+ <label for="<?php echo $this->get_field_id( 'title' ); ?>"> <?php _e( 'Title' ); ?></label>
92
+ <input class="widefat" id="<?php echo $this->get_field_id( 'title' ); ?>" name="<?php echo $this->get_field_name( 'title' ); ?>" type="text"<?php if ( isset( $instance['title'] ) ) : ?> value="<?php echo esc_attr( $instance['title'] ); ?>"<?php endif; ?>>
93
+ </p>
94
+
95
+ <?php
96
+ if ( $bpfwp_controller->settings->get_setting( 'multiple-locations' ) ) :
97
+
98
+ // Get an array of all locations with sane limits.
99
+ $locations = array();
100
+ $query = new WP_Query( array(
101
+ 'post_type' => array( $bpfwp_controller->cpts->location_cpt_slug ),
102
+ 'no_found_rows' => true,
103
+ 'update_post_meta_cache' => false,
104
+ 'update_post_term_cache' => false,
105
+ 'posts_per_page' => 500,
106
+ ) );
107
+ if ( $query->have_posts() ) {
108
+ while ( $query->have_posts() ) {
109
+ $query->next_post();
110
+ $locations[ $query->post->ID ] = $query->post->post_title;
111
+ }
112
+ }
113
+ wp_reset_postdata();
114
+ ?>
115
+
116
+ <p>
117
+ <label for="<?php echo $this->get_field_id( 'location' ); ?>"> <?php _e( 'Location' ); ?></label>
118
+ <select name="<?php echo $this->get_field_name( 'location' ); ?>" id="<?php echo $this->get_field_id( 'location' ); ?>" class="widefat">
119
+ <option><?php esc_html_e( 'Use Primary Business Profile' ); ?></option>
120
+ <?php foreach ( $locations as $id => $title ) : ?>
121
+ <option value="<?php echo absint( $id ); ?>"<?php if ( isset( $instance['location'] ) && $instance['location'] === $id ) : ?> selected<?php endif; ?>>
122
+ <?php esc_attr_e( $title ); ?>
123
+ </option>
124
+ <?php endforeach; ?>
125
+ </select>
126
+ </p>
127
+
128
+ <?php endif; // Locations. ?>
129
+
130
+ <?php foreach ( $this->toggles as $id => $label ) : ?>
131
+
132
+ <p>
133
+ <input type="checkbox" id="<?php echo $this->get_field_id( $id ); ?>" name="<?php echo $this->get_field_name( $id ); ?>" value="1"<?php if ( ! empty( $instance[ $id ] ) ) : ?> checked="checked"<?php endif; ?>>
134
+ <label for="<?php echo $this->get_field_id( $id ); ?>"> <?php echo $label; ?></label>
135
+ </p>
136
+
137
+ <?php endforeach;
138
+ }
139
+
140
+ /**
141
+ * Sanitize and save the widget form values.
142
+ *
143
+ * @since 1.0
144
+ * @access public
145
+ * @param array $new_instance New settings for this instance as input by the user via form().
146
+ * @param array $old_instance Old settings for this instance.
147
+ * @return array $instance Settings to be saved.
148
+ */
149
+ public function update( $new_instance, $old_instance ) {
150
+
151
+ $instance = array();
152
+ if ( ! empty( $new_instance['title'] ) ) {
153
+ $instance['title'] = strip_tags( $new_instance['title'] );
154
+ }
155
+
156
+ if ( ! empty( $new_instance['location'] ) ) {
157
+ $instance['location'] = absint( $new_instance['location'] );
158
+ }
159
+
160
+ foreach ( $this->toggles as $id => $label ) {
161
+ $instance[ $id ] = empty( $new_instance[ $id ] ) ? false : true;
162
+ }
163
+
164
+ return $instance;
165
+ }
166
+ }
167
+ endif;
includes/class-custom-post-types.php ADDED
@@ -0,0 +1,562 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Methods for our location custom post types.
4
+ *
5
+ * @package BusinessProfile
6
+ * @copyright Copyright (c) 2016, Theme of the Crop
7
+ * @license GPL-2.0+
8
+ * @since 1.1.0
9
+ */
10
+
11
+ defined( 'ABSPATH' ) || exit;
12
+
13
+ if ( ! class_exists( 'bpfwpCustomPostTypes', false ) ) :
14
+
15
+ /**
16
+ * Class to handle custom post type and post meta fields
17
+ *
18
+ * @since 1.1
19
+ */
20
+ class bpfwpCustomPostTypes {
21
+
22
+ /**
23
+ * Location post type slug
24
+ *
25
+ * @since 1.1
26
+ * @access public
27
+ * @var string
28
+ */
29
+ public $location_cpt_slug = 'location';
30
+
31
+ /**
32
+ * Register hooks
33
+ *
34
+ * @since 1.1
35
+ * @access public
36
+ * @return void
37
+ */
38
+ public function run() {
39
+ add_action( 'init', array( $this, 'load_cpts' ) );
40
+ add_action( 'add_meta_boxes', array( $this, 'add_meta_boxes' ) );
41
+ add_action( 'edit_form_after_title', array( $this, 'add_meta_nonce' ) );
42
+ add_action( 'save_post', array( $this, 'save_meta' ) );
43
+ add_action( 'current_screen', array( $this, 'maybe_flush_rewrite_rules' ) );
44
+ add_action( 'the_content', array( $this, 'append_to_content' ) );
45
+ }
46
+
47
+ /**
48
+ * Register custom post types
49
+ *
50
+ * @since 1.1
51
+ * @access public
52
+ * @return void
53
+ */
54
+ public function load_cpts() {
55
+
56
+ // Define the booking custom post type.
57
+ $args = array(
58
+ 'labels' => array(
59
+ 'name' => __( 'Locations', 'business-profile' ),
60
+ 'singular_name' => __( 'Location', 'business-profile' ),
61
+ 'menu_name' => __( 'Locations', 'business-profile' ),
62
+ 'name_admin_bar' => __( 'Locations', 'business-profile' ),
63
+ 'add_new' => __( 'Add New', 'business-profile' ),
64
+ 'add_new_item' => __( 'Add New Location', 'business-profile' ),
65
+ 'edit_item' => __( 'Edit Location', 'business-profile' ),
66
+ 'new_item' => __( 'New Location', 'business-profile' ),
67
+ 'view_item' => __( 'View Location', 'business-profile' ),
68
+ 'search_items' => __( 'Search Locations', 'business-profile' ),
69
+ 'not_found' => __( 'No locations found', 'business-profile' ),
70
+ 'not_found_in_trash' => __( 'No locations found in trash', 'business-profile' ),
71
+ 'all_items' => __( 'All Locations', 'business-profile' ),
72
+ ),
73
+ 'public' => true,
74
+ 'show_in_menu' => 'bpfwp-locations',
75
+ 'has_archive' => true,
76
+ );
77
+
78
+ $this->location_cpt_slug = apply_filters( 'bpfwp_location_cpt_slug', $this->location_cpt_slug );
79
+
80
+ // Create filter so addons can modify the arguments.
81
+ $args = apply_filters( 'bpfwp_location_cpt_args', $args );
82
+
83
+ // Register the post type.
84
+ register_post_type( $this->location_cpt_slug, $args );
85
+ }
86
+
87
+ /**
88
+ * Flush the rewrite rules
89
+ *
90
+ * This should only be called on plugin activation.
91
+ *
92
+ * @since 1.1
93
+ * @access public
94
+ * @return void
95
+ */
96
+ public function flush_rewrite_rules() {
97
+
98
+ // Load CPTs before flushing, as recommended in the Codex.
99
+ $this->load_cpts();
100
+
101
+ flush_rewrite_rules();
102
+ }
103
+
104
+ /**
105
+ * Maybe flush the rewrite rules if the multiple locations option has
106
+ * been turned on.
107
+ *
108
+ * Should only be run on the Business Profile settings page
109
+ *
110
+ * @since 1.1
111
+ * @access public
112
+ * @param string $current_screen The current admin screen slug.
113
+ * @return void
114
+ */
115
+ public function maybe_flush_rewrite_rules( $current_screen ) {
116
+
117
+ global $admin_page_hooks;
118
+ if ( empty( $admin_page_hooks['bpfwp-locations'] ) || $current_screen->base !== $admin_page_hooks['bpfwp-locations'] . '_page_bpfwp-settings' ) {
119
+ return;
120
+ }
121
+
122
+ if ( ! bpfwp_setting( 'multiple-locations' ) ) {
123
+ return;
124
+ }
125
+
126
+ $rules = get_option( 'rewrite_rules' );
127
+ if ( ! array_key_exists( $this->location_cpt_slug . '/?$', $rules ) ) {
128
+ $this->flush_rewrite_rules();
129
+ }
130
+ }
131
+
132
+ /**
133
+ * Add meta boxes when adding/editing locations
134
+ *
135
+ * @since 1.1
136
+ * @access public
137
+ * @return void
138
+ */
139
+ public function add_meta_boxes() {
140
+
141
+ $meta_boxes = array(
142
+
143
+ // Metabox to enter schema type.
144
+ array(
145
+ 'id' => 'bpfwp_schema_metabox',
146
+ 'title' => __( 'Schema Type', 'business-profile' ),
147
+ 'callback' => array( $this, 'print_schema_metabox' ),
148
+ 'post_type' => $this->location_cpt_slug,
149
+ 'context' => 'side',
150
+ 'priority' => 'default',
151
+ ),
152
+
153
+ // Metabox to enter phone number, contact email address and
154
+ // select a contact page.
155
+ array(
156
+ 'id' => 'bpfwp_contact_metabox',
157
+ 'title' => __( 'Contact Details', 'business-profile' ),
158
+ 'callback' => array( $this, 'print_contact_metabox' ),
159
+ 'post_type' => $this->location_cpt_slug,
160
+ 'context' => 'side',
161
+ 'priority' => 'default',
162
+ ),
163
+
164
+ // Metabox to enter opening hours.
165
+ array(
166
+ 'id' => 'bpfwp_opening_hours_metabox',
167
+ 'title' => __( 'Opening Hours', 'business-profile' ),
168
+ 'callback' => array( $this, 'print_opening_hours_metabox' ),
169
+ 'post_type' => $this->location_cpt_slug,
170
+ 'context' => 'normal',
171
+ 'priority' => 'default',
172
+ ),
173
+
174
+ );
175
+
176
+ // Create filter so addons can modify the metaboxes.
177
+ $meta_boxes = apply_filters( 'bpfwp_meta_boxes', $meta_boxes );
178
+
179
+ // Create the metaboxes.
180
+ foreach ( $meta_boxes as $meta_box ) {
181
+ add_meta_box(
182
+ $meta_box['id'],
183
+ $meta_box['title'],
184
+ $meta_box['callback'],
185
+ $meta_box['post_type'],
186
+ $meta_box['context'],
187
+ $meta_box['priority']
188
+ );
189
+ }
190
+ }
191
+
192
+ /**
193
+ * Output a hidden nonce field to secure the saving of post meta
194
+ *
195
+ * @since 1.1
196
+ * @access public
197
+ * @return void
198
+ */
199
+ public function add_meta_nonce() {
200
+ global $post;
201
+ if ( $post->post_type === $this->location_cpt_slug ) {
202
+ wp_nonce_field( 'bpfwp_location_meta', 'bpfwp_location_meta_nonce' );
203
+ }
204
+ }
205
+
206
+ /**
207
+ * Output the metabox HTML to select a schema type
208
+ *
209
+ * @since 1.1
210
+ * @access public
211
+ * @param WP_Post $post The current post object.
212
+ * @return void
213
+ */
214
+ public function print_schema_metabox( $post ) {
215
+
216
+ global $bpfwp_controller;
217
+ $schema_types = $bpfwp_controller->settings->get_schema_types();
218
+ $selected = bpfwp_setting( 'schema-type', $post->ID );
219
+
220
+ // Fall back to general setting.
221
+ if ( empty( $selected ) ) {
222
+ $selected = bpfwp_setting( 'schema-type' );
223
+ }
224
+ ?>
225
+
226
+ <div class="bpfwp-meta-input bpfwp-meta-schema-type">
227
+ <label for="bpfwp_schema-type">
228
+ <?php esc_html_e( 'Schema type', 'business-profile' ); ?>
229
+ </label>
230
+ <select name="schema_type" id="bpfwp_schema-type" aria-describedby="bpfwp_schema-type_description">
231
+ <?php foreach ( $schema_types as $key => $label ) : ?>
232
+ <option value="<?php esc_attr_e( $key ); ?>"<?php if ( $selected === $key ) : ?> selected<?php endif; ?>>
233
+ <?php esc_attr_e( $label ); ?>
234
+ </option>
235
+ <?php endforeach; ?>
236
+ </select>
237
+ <p class="description" id="bpfwp_schema-type_description">
238
+ <?php esc_html_e( 'Select the option that best describes your business to improve how search engines understand your website.', 'business-profile' ); ?>
239
+ <a href="http://schema.org/" target="_blank">Schema.org</a>
240
+ </p>
241
+ </div>
242
+
243
+ <?php
244
+ }
245
+
246
+ /**
247
+ * Output the metabox HTML to enter a phone number,
248
+ * contact email address and select a contact page.
249
+ *
250
+ * @since 1.1
251
+ * @access public
252
+ * @param WP_Post $post The current post object.
253
+ * @return void
254
+ */
255
+ public function print_contact_metabox( $post ) {
256
+
257
+ // Address mimics HTML markup from Simple Admin Pages component.
258
+ wp_enqueue_script( 'bpfwp-admin-location-address', BPFWP_PLUGIN_URL . '/lib/simple-admin-pages/js/address.js', array( 'jquery' ) );
259
+ wp_localize_script(
260
+ 'bpfwp-admin-location-address',
261
+ 'sap_address',
262
+ array(
263
+ 'strings' => array(
264
+ 'no-setting' => __( 'No map coordinates set.', 'business-profile' ),
265
+ 'sep-lat-lon' => _x( ', ', 'separates latitude and longitude', 'business-profile' ),
266
+ 'retrieving' => __( 'Requesting new coordinates', 'business-profile' ),
267
+ 'select' => __( 'Select a match below', 'business-profile' ),
268
+ 'view' => __( 'View', 'business-profile' ),
269
+ 'result_error' => __( 'Error', 'business-profile' ),
270
+ 'result_invalid' => __( 'Invalid request. Be sure to fill out the address field before retrieving coordinates.', 'business-profile' ),
271
+ 'result_denied' => __( 'Request denied.', 'business-profile' ),
272
+ 'result_limit' => __( 'Request denied because you are over your request quota.', 'business-profile' ),
273
+ 'result_empty' => __( 'Nothing was found at that address.', 'business-profile' ),
274
+ ),
275
+ )
276
+ );
277
+ ?>
278
+
279
+ <div class="bpfwp-meta-input bpfwp-meta-geo_address sap-address">
280
+ <textarea name="geo_address" id="bpfwp_address"><?php echo esc_textarea( get_post_meta( $post->ID, 'geo_address', true ) ); ?></textarea>
281
+ <p class="sap-map-coords-wrapper">
282
+ <span class="dashicons dashicons-location-alt"></span>
283
+ <span class="sap-map-coords">
284
+ <?php
285
+ $geo_latitude = get_post_meta( $post->ID, 'geo_latitude', true );
286
+ $geo_longitude = get_post_meta( $post->ID, 'geo_longitude', true );
287
+ if ( empty( $geo_latitude ) || empty( $geo_longitude ) ) :
288
+ esc_html_e( 'No map coordinates set.', 'business-profile' );
289
+ else : ?>
290
+ <?php echo get_post_meta( $post->ID, 'geo_latitude', true ) . esc_html_x( ', ', 'separates latitude and longitude', 'business-profile' ) . get_post_meta( $post->ID, 'geo_longitude', true ); ?>
291
+ <a href="//maps.google.com/maps?q=<?php echo esc_attr( get_post_meta( $post->ID, 'geo_latitude', true ) ) . ',' . esc_attr( get_post_meta( $post->ID, 'geo_longitude', true ) ); ?>" class="sap-view-coords" target="_blank"><?php esc_html_e( 'View', 'business-profile' ); ?></a>
292
+ <?php
293
+ endif; ?>
294
+ </span>
295
+ </p>
296
+ <p class="sap-coords-action-wrapper">
297
+ <a href="#" class="sap-get-coords">
298
+ <?php esc_html_e( 'Retrieve map coordinates', 'business-profile' ); ?>
299
+ </a>
300
+ <?php echo esc_html_x( ' | ', 'separator between admin action links in address component', 'business-profile' ); ?>
301
+ <a href="#" class="sap-remove-coords">
302
+ <?php esc_html_e( 'Remove map coordinates', 'business-profile' ); ?>
303
+ </a>
304
+ </p>
305
+ <input type="hidden" class="lat" name="geo_latitude" value="<?php echo esc_attr( get_post_meta( $post->ID, 'geo_latitude', true ) ); ?>">
306
+ <input type="hidden" class="lon" name="geo_longitude" value="<?php echo esc_attr( get_post_meta( $post->ID, 'geo_longitude', true ) ); ?>">
307
+ </div>
308
+
309
+ <?php
310
+ // Get an array of all pages with sane limits.
311
+ $pages = array();
312
+ $query = new WP_Query( array(
313
+ 'post_type' => array( 'page' ),
314
+ 'no_found_rows' => true,
315
+ 'update_post_meta_cache' => false,
316
+ 'update_post_term_cache' => false,
317
+ 'posts_per_page' => 500,
318
+ ) );
319
+ if ( $query->have_posts() ) {
320
+ while ( $query->have_posts() ) {
321
+ $query->next_post();
322
+ $pages[ $query->post->ID ] = $query->post->post_title;
323
+ }
324
+ }
325
+ wp_reset_postdata();
326
+ ?>
327
+
328
+ <div class="bpfwp-meta-input bpfwp-meta-contact-page">
329
+ <label for="bpfwp_contact-page">
330
+ <?php esc_html_e( 'Contact Page', 'business-profile' ); ?>
331
+ </label>
332
+ <select name="contact_post" id="bpfwp_contact-page">
333
+ <option></option>
334
+ <?php foreach ( $pages as $id => $title ) : ?>
335
+ <option value="<?php echo absint( $id ); ?>"<?php if ( get_post_meta( $post->ID, 'contact_post', true ) == $id ) : ?> selected<?php endif; ?>>
336
+ <?php esc_attr_e( $title ); ?>
337
+ </option>
338
+ <?php endforeach; ?>
339
+ </select>
340
+ </div>
341
+
342
+ <div class="bpfwp-meta-input bpfwp-meta-contact-email">
343
+ <label for="bpfwp_contact-email">
344
+ <?php esc_html_e( 'Email Address (optional)', 'business-profile' ); ?>
345
+ </label>
346
+ <input type="email" name="contact_email" id="bpfwp_contact-email" value="<?php esc_attr_e( get_post_meta( $post->ID, 'contact_email', true ) ); ?>">
347
+ </div>
348
+
349
+ <div class="bpfwp-meta-input bpfwp-meta-phone">
350
+ <label for="bpfwp_phone">
351
+ <?php esc_html_e( 'Phone Number', 'business-profile' ); ?>
352
+ </label>
353
+ <input type="tel" name="phone" id="bpfwp_phone" value="<?php esc_attr_e( get_post_meta( $post->ID, 'phone', true ) ); ?>">
354
+ </div>
355
+
356
+ <?php
357
+ }
358
+
359
+ /**
360
+ * Output the metabox HTML to define opening hours
361
+ *
362
+ * @since 1.1
363
+ * @access public
364
+ * @param WP_Post $post The current post object.
365
+ * @return void
366
+ */
367
+ public function print_opening_hours_metabox( $post ) {
368
+
369
+ $scheduler = $this->get_scheduler_meta_object( get_post_meta( $post->ID, 'opening_hours', true ) );
370
+
371
+ // Load required scripts and styles.
372
+ wp_enqueue_style( 'bpfwp-admin-location-sap', BPFWP_PLUGIN_URL . '/lib/simple-admin-pages/css/admin.css' );
373
+ foreach ( $scheduler->styles as $handle => $style ) {
374
+ wp_enqueue_style( $handle, BPFWP_PLUGIN_URL . '/lib/simple-admin-pages/' . $style['path'], $style['dependencies'], $style['version'], $style['media'] );
375
+ }
376
+ foreach ( $scheduler->scripts as $handle => $script ) {
377
+ wp_enqueue_script( $handle, BPFWP_PLUGIN_URL . '/lib/simple-admin-pages/' . $script['path'], $script['dependencies'], $script['version'], $script['footer'] );
378
+ }
379
+ ?>
380
+
381
+ <div class="bpfwp-meta-input bpfwp-meta-opening-hours">
382
+ <?php $scheduler->display_setting(); ?>
383
+ </div>
384
+
385
+ <?php
386
+ }
387
+
388
+ /**
389
+ * Get a modified Scheduler object from the Simple Admin Pages library
390
+ *
391
+ * This modified scheduler is used to display and sanitize a scheduler
392
+ * component on the location post editing screen.
393
+ *
394
+ * @since 1.1
395
+ * @access public
396
+ * @see lib/simple-admin-pages/classes/AdminPageSetting.Scheduler.class.php
397
+ * @param string $values Optional values to be set.
398
+ * @return bpfwpSAPSchedulerMeta $scheduler An instance of the scheduler class.
399
+ */
400
+ public function get_scheduler_meta_object( $values = null ) {
401
+
402
+ require_once BPFWP_PLUGIN_DIR . '/includes/class-sap-scheduler-meta.php';
403
+ $scheduler = new bpfwpSAPSchedulerMeta(
404
+ array(
405
+ 'page' => 'dummy_page', // Required but not used.
406
+ 'id' => 'opening_hours',
407
+ 'title' => __( 'Opening Hours', 'business-profile' ),
408
+ 'description' => __( 'Define your weekly opening hours by adding scheduling rules.', 'business-profile' ),
409
+ 'weekdays' => array(
410
+ 'monday' => _x( 'Mo', 'Monday abbreviation', 'business-profile' ),
411
+ 'tuesday' => _x( 'Tu', 'Tuesday abbreviation', 'business-profile' ),
412
+ 'wednesday' => _x( 'We', 'Wednesday abbreviation', 'business-profile' ),
413
+ 'thursday' => _x( 'Th', 'Thursday abbreviation', 'business-profile' ),
414
+ 'friday' => _x( 'Fr', 'Friday abbreviation', 'business-profile' ),
415
+ 'saturday' => _x( 'Sa', 'Saturday abbreviation', 'business-profile' ),
416
+ 'sunday' => _x( 'Su', 'Sunday abbreviation', 'business-profile' ),
417
+ ),
418
+ 'time_format' => _x( 'h:i A', 'Time format displayed in the opening hours setting panel in your admin area. Must match formatting rules at http://amsul.ca/pickadate.js/time.htm#formats', 'business-profile' ),
419
+ 'date_format' => _x( 'mmmm d, yyyy', 'Date format displayed in the opening hours setting panel in your admin area. Must match formatting rules at http://amsul.ca/pickadate.js/date.htm#formatting-rules', 'business-profile' ),
420
+ 'disable_weeks' => true,
421
+ 'disable_date' => true,
422
+ 'strings' => array(
423
+ 'add_rule' => __( 'Add another opening time', 'business-profile' ),
424
+ 'weekly' => _x( 'Weekly', 'Format of a scheduling rule', 'business-profile' ),
425
+ 'monthly' => _x( 'Monthly', 'Format of a scheduling rule', 'business-profile' ),
426
+ 'date' => _x( 'Date', 'Format of a scheduling rule', 'business-profile' ),
427
+ 'weekdays' => _x( 'Days of the week', 'Label for selecting days of the week in a scheduling rule', 'business-profile' ),
428
+ 'month_weeks' => _x( 'Weeks of the month', 'Label for selecting weeks of the month in a scheduling rule', 'business-profile' ),
429
+ 'date_label' => _x( 'Date', 'Label to select a date for a scheduling rule', 'business-profile' ),
430
+ 'time_label' => _x( 'Time', 'Label to select a time slot for a scheduling rule', 'business-profile' ),
431
+ 'allday' => _x( 'All day', 'Label to set a scheduling rule to last all day', 'business-profile' ),
432
+ 'start' => _x( 'Start', 'Label for the starting time of a scheduling rule', 'business-profile' ),
433
+ 'end' => _x( 'End', 'Label for the ending time of a scheduling rule', 'business-profile' ),
434
+ 'set_time_prompt' => _x( 'All day long. Want to %sset a time slot%s?', 'Prompt displayed when a scheduling rule is set without any time restrictions', 'business-profile' ),
435
+ 'toggle' => _x( 'Open and close this rule', 'Toggle a scheduling rule open and closed', 'business-profile' ),
436
+ 'delete' => _x( 'Delete rule', 'Delete a scheduling rule', 'business-profile' ),
437
+ 'delete_schedule' => __( 'Delete scheduling rule', 'business-profile' ),
438
+ 'never' => _x( 'Never', 'Brief default description of a scheduling rule when no weekdays or weeks are included in the rule', 'business-profile' ),
439
+ 'weekly_always' => _x( 'Every day', 'Brief default description of a scheduling rule when all the weekdays/weeks are included in the rule', 'business-profile' ),
440
+ 'monthly_weekdays' => _x( '%s on the %s week of the month', 'Brief default description of a scheduling rule when some weekdays are included on only some weeks of the month. %s should be left alone and will be replaced by a comma-separated list of days and weeks in the following format: M, T, W on the first, second week of the month', 'business-profile' ),
441
+ 'monthly_weeks' => _x( '%s week of the month', 'Brief default description of a scheduling rule when some weeks of the month are included but all or no weekdays are selected. %s should be left alone and will be replaced by a comma-separated list of weeks in the following format: First, second week of the month', 'business-profile' ),
442
+ 'all_day' => _x( 'All day', 'Brief default description of a scheduling rule when no times are set', 'business-profile' ),
443
+ 'before' => _x( 'Ends at', 'Brief default description of a scheduling rule when an end time is set but no start time. If the end time is 6pm, it will read: Ends at 6pm', 'business-profile' ),
444
+ 'after' => _x( 'Starts at', 'Brief default description of a scheduling rule when a start time is set but no end time. If the start time is 6pm, it will read: Starts at 6pm', 'business-profile' ),
445
+ 'separator' => _x( '&mdash;', 'Separator between times of a scheduling rule', 'business-profile' ),
446
+ ),
447
+ )
448
+ );
449
+
450
+ if ( ! empty( $values ) ) {
451
+ $scheduler->set_value( $values );
452
+ }
453
+
454
+ return $scheduler;
455
+ }
456
+
457
+ /**
458
+ * Sanitize and save the post meta
459
+ *
460
+ * The actual sanitization and validation should be
461
+ * performed in a bpfwpLocation object which will
462
+ * handle all the location data, and perform loading
463
+ * and saving.
464
+ *
465
+ * @since 1.1
466
+ * @access public
467
+ * @param int $post_id The current post ID.
468
+ * @return int $post_id The current post ID.
469
+ */
470
+ public function save_meta( $post_id ) {
471
+ if ( ! isset( $_POST['bpfwp_location_meta_nonce'] ) || ! wp_verify_nonce( sanitize_key( $_POST['bpfwp_location_meta_nonce'] ), 'bpfwp_location_meta' ) ) { // Input var okay.
472
+ return $post_id;
473
+ }
474
+
475
+ if ( ! isset( $_POST['post_type'] ) || $_POST['post_type'] !== $this->location_cpt_slug ) { // Input var okay.
476
+ return $post_id;
477
+ }
478
+
479
+ if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
480
+ return $post_id;
481
+ }
482
+
483
+ if ( ! current_user_can( 'edit_post', $post_id ) ) {
484
+ return $post_id;
485
+ }
486
+
487
+ $post_meta = array(
488
+ 'schema_type' => 'sanitize_text_field',
489
+ 'geo_address' => 'wp_kses_post',
490
+ 'geo_latitude' => 'sanitize_text_field',
491
+ 'geo_longitude' => 'sanitize_text_field',
492
+ 'phone' => 'sanitize_text_field',
493
+ 'contact_post' => 'absint',
494
+ 'contact_email' => 'sanitize_email',
495
+ 'opening_hours' => array( $this, 'sanitize_opening_hours' ),
496
+ );
497
+
498
+ foreach ( $post_meta as $key => $sanitizer ) {
499
+
500
+ if ( ! isset( $_POST[ $key ] ) ) { // Input var okay.
501
+ $_POST[ $key ] = '';
502
+ }
503
+
504
+ $cur = get_post_meta( $post_id, $key, true );
505
+ $new = call_user_func( $sanitizer, wp_unslash( $_POST[ $key ] ) ); // Input var okay.
506
+
507
+ if ( $new !== $cur ) {
508
+ update_post_meta( $post_id, $key, $new );
509
+ }
510
+ }
511
+
512
+ return $post_id;
513
+ }
514
+
515
+ /**
516
+ * Sanitize opening hours
517
+ *
518
+ * This is a wrapper for the sanitization callback in the Scheduler
519
+ * component of Simple Admin Pages
520
+ *
521
+ * @since 1.1
522
+ * @access public
523
+ * @see lib/simple-admin-pages/classes/AdminPageSetting.Scheduler.class.php
524
+ * @param array $values Raw values for the opening hours.
525
+ * @return array $values Sanitized values for the opening hours.
526
+ */
527
+ public function sanitize_opening_hours( $values ) {
528
+ $scheduler = $this->get_scheduler_meta_object( $values );
529
+ return $scheduler->sanitize_callback_wrapper( $values );
530
+ }
531
+
532
+ /**
533
+ * Automatically append a contact card to `the_content` on location
534
+ * single pages
535
+ *
536
+ * @since 1.1
537
+ * @access public
538
+ * @param string $content The current WordPress content.
539
+ * @return string $content The modified WordPress content.
540
+ */
541
+ public function append_to_content( $content ) {
542
+
543
+ if ( ! is_main_query() || ! in_the_loop() || post_password_required() ) {
544
+ return $content;
545
+ }
546
+
547
+ global $bpfwp_controller;
548
+
549
+ if ( $bpfwp_controller->get_theme_support( 'disable_append_to_content' ) ) {
550
+ return $content;
551
+ }
552
+
553
+ global $post;
554
+
555
+ if ( ! $post instanceof WP_Post || $post->post_type !== $bpfwp_controller->cpts->location_cpt_slug ) {
556
+ return $content;
557
+ }
558
+
559
+ return $content . '[contact-card location=' . $post->ID . ' show_name=0]';
560
+ }
561
+ }
562
+ endif;
includes/class-sap-scheduler-meta.php ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Extend the Simple Admin Pages Scheduler component so that it can be used
4
+ * in the location custom post type editing screen.
5
+ *
6
+ * @see lib/simple-admin-pages/classes/AdminPageSetting.Scheduler.class.php
7
+ *
8
+ * @package BusinessProfile
9
+ * @copyright Copyright (c) 2016, Theme of the Crop
10
+ * @license GPL-2.0+
11
+ * @since 1.1
12
+ */
13
+
14
+ defined( 'ABSPATH' ) || exit;
15
+
16
+ require_once BPFWP_PLUGIN_DIR . '/lib/simple-admin-pages/classes/AdminPageSetting.Scheduler.class.php';
17
+
18
+ if ( ! class_exists( 'bpfwpSAPSchedulerMeta', false ) && class_exists( 'sapAdminPageSettingScheduler_2_0' ) ) :
19
+
20
+ /**
21
+ * Class to extend the Simple Admin Pages Scheduler component for use on
22
+ * the location custom post type editing screen
23
+ *
24
+ * @since 1.1
25
+ */
26
+ class bpfwpSAPSchedulerMeta extends sapAdminPageSettingScheduler_2_0 {
27
+
28
+ /**
29
+ * Generate an option input field name. The default component appends
30
+ * an admin page slug to the input field name. We only want the
31
+ * object ID, which will be the post meta key.
32
+ *
33
+ * @since 1.1
34
+ * @access public
35
+ * @return string $id The input ID.
36
+ */
37
+ public function get_input_name() {
38
+ return esc_attr( $this->id );
39
+ }
40
+ }
41
+ endif;
includes/class-settings.php ADDED
@@ -0,0 +1,477 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Define settings used throughout the plugin.
4
+ *
5
+ * @package BusinessProfile
6
+ * @copyright Copyright (c) 2016, Theme of the Crop
7
+ * @license GPL-2.0+
8
+ * @since 0.0.1
9
+ */
10
+
11
+ defined( 'ABSPATH' ) || exit;
12
+
13
+ if ( ! class_exists( 'bpfwpSettings' ) ) :
14
+
15
+ /**
16
+ * Class to handle configurable settings for Business Profile
17
+ *
18
+ * @since 0.0.1
19
+ */
20
+ class bpfwpSettings {
21
+
22
+ /**
23
+ * Default values for settings
24
+ *
25
+ * @since 0.0.1
26
+ * @access public
27
+ * @var array
28
+ */
29
+ public $defaults = array();
30
+
31
+ /**
32
+ * Default values for display settings
33
+ *
34
+ * @since 0.0.1
35
+ * @access public
36
+ * @var array
37
+ */
38
+ public $default_display_settings = array();
39
+
40
+ /**
41
+ * Stored values for settings
42
+ *
43
+ * @since 0.0.1
44
+ * @access public
45
+ * @var array
46
+ */
47
+ public $settings = array();
48
+
49
+ /**
50
+ * Initialize the class and register hooks.
51
+ *
52
+ * @since 0.0.1
53
+ * @access public
54
+ * @return void
55
+ */
56
+ public function __construct() {
57
+
58
+ add_action( 'init', array( $this, 'set_defaults' ) );
59
+
60
+ add_action( 'init', array( $this, 'load_settings_panel' ) );
61
+
62
+ }
63
+
64
+ /**
65
+ * Load the plugin's default settings
66
+ *
67
+ * @since 0.0.1
68
+ * @access public
69
+ * @return void
70
+ */
71
+ public function set_defaults() {
72
+
73
+ $this->defaults = array(
74
+ 'schema_type' => 'Organization',
75
+ 'name' => get_bloginfo( 'name' ),
76
+ );
77
+
78
+ $this->defaults = apply_filters( 'bpfwp_defaults', $this->defaults );
79
+ }
80
+
81
+ /**
82
+ * Get default display settings
83
+ *
84
+ * Controls default visibility of elements in the contact card as well
85
+ * as when template functions, like bpfwp_print_name, are called
86
+ * directly.
87
+ *
88
+ * @since 1.1
89
+ * @access public
90
+ * @return array $default_display_settings The display settings defaults.
91
+ */
92
+ public function get_default_display_settings() {
93
+
94
+ if ( ! empty( $this->default_display_settings ) ) {
95
+ return $this->default_display_settings;
96
+ }
97
+
98
+ $this->default_display_settings = apply_filters(
99
+ 'bpfwp_default_display_settings',
100
+ array(
101
+ 'location' => false,
102
+ 'show_name' => true,
103
+ 'show_address' => true,
104
+ 'show_get_directions' => true,
105
+ 'show_phone' => true,
106
+ 'show_contact' => true,
107
+ 'show_opening_hours' => true,
108
+ 'show_opening_hours_brief' => false,
109
+ 'show_map' => true,
110
+ )
111
+ );
112
+
113
+ return $this->default_display_settings;
114
+ }
115
+
116
+ /**
117
+ * Get a setting's value or fallback to a default if one exists
118
+ *
119
+ * @since 0.0.1
120
+ * @access public
121
+ * @param string $setting The setting to retrieve.
122
+ * @param string $location The location where the setting is used.
123
+ * @return mixed A setting based on the key provided.
124
+ */
125
+ public function get_setting( $setting, $location = false ) {
126
+
127
+ // Most settings are named with hyphens, but the schema_type uses
128
+ // an underscore. This just provides a small convenience by allowing
129
+ // users to look up the setting by `schema-type`.
130
+ if ( 'schema-type' === $setting ) {
131
+ $setting = 'schema_type';
132
+ }
133
+
134
+ if ( empty( $location ) ) {
135
+ if ( empty( $this->settings ) ) {
136
+ $this->settings = get_option( 'bpfwp-settings' );
137
+ }
138
+
139
+ if ( ! empty( $this->settings[ $setting ] ) ) {
140
+ return $this->settings[ $setting ];
141
+ }
142
+
143
+ if ( ! empty( $this->defaults[ $setting ] ) ) {
144
+ return $this->defaults[ $setting ];
145
+ }
146
+ } else {
147
+
148
+ // Map setting slugs to post data.
149
+ switch ( $setting ) {
150
+
151
+ case 'schema_type' :
152
+ return get_post_meta( $location, 'schema_type', true );
153
+
154
+ case 'name' :
155
+ return get_the_title( $location );
156
+
157
+ case 'description' :
158
+ return get_the_content( $location );
159
+
160
+ case 'address' :
161
+ return array(
162
+ 'text' => get_post_meta( $location, 'geo_address', true ),
163
+ 'lat' => get_post_meta( $location, 'geo_latitude', true ),
164
+ 'lon' => get_post_meta( $location, 'geo_longitude', true ),
165
+ );
166
+
167
+ case 'phone' :
168
+ return get_post_meta( $location, 'phone', true );
169
+
170
+ case 'contact-page' :
171
+ return get_post_meta( $location, 'contact_post', true );
172
+
173
+ case 'contact-email' :
174
+ return get_post_meta( $location, 'contact_email', true );
175
+
176
+ case 'opening-hours' :
177
+ return get_post_meta( $location, 'opening_hours', true );
178
+ }
179
+ }
180
+
181
+ return null;
182
+ }
183
+
184
+ /**
185
+ * Load the admin settings page.
186
+ *
187
+ * @since 0.0.1
188
+ * @access public
189
+ * @link https://github.com/NateWr/simple-admin-pages
190
+ */
191
+ public function load_settings_panel() {
192
+
193
+ require_once BPFWP_PLUGIN_DIR . '/lib/simple-admin-pages/simple-admin-pages.php';
194
+ $sap = sap_initialize_library(
195
+ $args = array(
196
+ 'version' => '2.0',
197
+ 'lib_url' => BPFWP_PLUGIN_URL . '/lib/simple-admin-pages/',
198
+ )
199
+ );
200
+
201
+ // Multiple location mode.
202
+ if ( $this->get_setting( 'multiple-locations' ) ) {
203
+
204
+ $sap->add_page(
205
+ 'menu',
206
+ array(
207
+ 'id' => 'bpfwp-locations',
208
+ 'title' => __( 'Locations', 'business-profile' ),
209
+ 'menu_title' => __( 'Locations', 'business-profile' ),
210
+ 'capability' => 'manage_options',
211
+ 'icon' => 'dashicons-location',
212
+ 'position' => null,
213
+ )
214
+ );
215
+
216
+ $sap->add_page(
217
+ 'submenu',
218
+ array(
219
+ 'id' => 'bpfwp-settings',
220
+ 'parent_menu' => 'bpfwp-locations',
221
+ 'title' => __( 'Business Profile', 'business-profile' ),
222
+ 'menu_title' => __( 'Business Profile', 'business-profile' ),
223
+ 'capability' => 'manage_options',
224
+ )
225
+ );
226
+ // Single location mode.
227
+ } else {
228
+
229
+ $sap->add_page(
230
+ 'menu',
231
+ array(
232
+ 'id' => 'bpfwp-settings',
233
+ 'title' => __( 'Business Profile', 'business-profile' ),
234
+ 'menu_title' => __( 'Business Profile', 'business-profile' ),
235
+ 'capability' => 'manage_options',
236
+ 'icon' => 'dashicons-businessman',
237
+ 'position' => null,
238
+ )
239
+ );
240
+
241
+ }
242
+
243
+ $sap->add_section(
244
+ 'bpfwp-settings',
245
+ array(
246
+ 'id' => 'bpfwp-seo',
247
+ 'title' => __( 'Search Engine Optimization', 'business-profile' ),
248
+ )
249
+ );
250
+
251
+ $sap->add_setting(
252
+ 'bpfwp-settings',
253
+ 'bpfwp-seo',
254
+ 'select',
255
+ array(
256
+ 'id' => 'schema_type',
257
+ 'title' => __( 'Schema Type', 'business-profile' ),
258
+ 'description' => __( 'Select the option that best describes your business to improve how search engines understand your website', 'business-profile' ) . ' <a href="http://schema.org/" target="_blank">Schema.org</a>',
259
+ 'blank_option' => false,
260
+ 'options' => $this->get_schema_types(),
261
+ )
262
+ );
263
+
264
+ $sap->add_section(
265
+ 'bpfwp-settings',
266
+ array(
267
+ 'id' => 'bpfwp-contact',
268
+ 'title' => __( 'Contact Information', 'business-profile' ),
269
+ )
270
+ );
271
+
272
+ $sap->add_setting(
273
+ 'bpfwp-settings',
274
+ 'bpfwp-contact',
275
+ 'text',
276
+ array(
277
+ 'id' => 'name',
278
+ 'title' => __( 'Name', 'business-profile' ),
279
+ 'description' => __( 'Enter the name of your business if it is different than the website name.', 'business-profile' ),
280
+ 'placeholder' => $this->defaults['name'],
281
+ )
282
+ );
283
+
284
+ $sap->add_setting(
285
+ 'bpfwp-settings',
286
+ 'bpfwp-contact',
287
+ 'address',
288
+ array(
289
+ 'id' => 'address',
290
+ 'title' => __( 'Address', 'business-profile' ),
291
+ 'strings' => array(
292
+ 'sep-action-links' => _x( ' | ', 'separator between admin action links in address component', 'business-profile' ),
293
+ 'sep-lat-lon' => _x( ', ', 'separates latitude and longitude', 'business-profile' ),
294
+ 'no-setting' => __( 'No map coordinates set.', 'business-profile' ),
295
+ 'retrieving' => __( 'Requesting new coordinates', 'business-profile' ),
296
+ 'select' => __( 'Select a match below', 'business-profile' ),
297
+ 'view' => __( 'View', 'business-profile' ),
298
+ 'retrieve' => __( 'Retrieve map coordinates', 'business-profile' ),
299
+ 'remove' => __( 'Remove map coordinates', 'business-profile' ),
300
+ 'try_again' => __( 'Try again?', 'business-profile' ),
301
+ 'result_error' => __( 'Error', 'business-profile' ),
302
+ 'result_invalid' => __( 'Invalid request. Be sure to fill out the address field before retrieving coordinates.', 'business-profile' ),
303
+ 'result_denied' => __( 'Request denied.', 'business-profile' ),
304
+ 'result_limit' => __( 'Request denied because you are over your request quota.', 'business-profile' ),
305
+ 'result_empty' => __( 'Nothing was found at that address', 'business-profile' ),
306
+ ),
307
+ )
308
+ );
309
+
310
+ $sap->add_setting(
311
+ 'bpfwp-settings',
312
+ 'bpfwp-contact',
313
+ 'text',
314
+ array(
315
+ 'id' => 'phone',
316
+ 'title' => __( 'Phone', 'business-profile' ),
317
+ )
318
+ );
319
+
320
+ $sap->add_setting(
321
+ 'bpfwp-settings',
322
+ 'bpfwp-contact',
323
+ 'post',
324
+ array(
325
+ 'id' => 'contact-page',
326
+ 'title' => __( 'Contact Page', 'business-profile' ),
327
+ 'description' => __( 'Select a page on your site where users can reach you, such as a contact form.', 'business-profile' ),
328
+ 'blank_option' => true,
329
+ 'args' => array(
330
+ 'post_type' => 'page',
331
+ 'posts_per_page' => -1,
332
+ 'post_status' => 'publish',
333
+ ),
334
+ )
335
+ );
336
+
337
+ $sap->add_setting(
338
+ 'bpfwp-settings',
339
+ 'bpfwp-contact',
340
+ 'text',
341
+ array(
342
+ 'id' => 'contact-email',
343
+ 'title' => __( 'Email Address (optional)', 'business-profile' ),
344
+ 'description' => __( 'Enter an email address only if you want to display this publicly. Showing your email address on your site may cause you to receive excessive spam.', 'business-profile' ),
345
+ )
346
+ );
347
+
348
+ $sap->add_section(
349
+ 'bpfwp-settings',
350
+ array(
351
+ 'id' => 'bpfwp-schedule',
352
+ 'title' => __( 'Schedule', 'business-profile' ),
353
+ )
354
+ );
355
+
356
+ $sap->add_setting(
357
+ 'bpfwp-settings',
358
+ 'bpfwp-schedule',
359
+ 'scheduler',
360
+ array(
361
+ 'id' => 'opening-hours',
362
+ 'title' => __( 'Opening Hours', 'business-profile' ),
363
+ 'description' => __( 'Define your weekly opening hours by adding scheduling rules.', 'business-profile' ),
364
+ 'weekdays' => array(
365
+ 'monday' => _x( 'Mo', 'Monday abbreviation', 'business-profile' ),
366
+ 'tuesday' => _x( 'Tu', 'Tuesday abbreviation', 'business-profile' ),
367
+ 'wednesday' => _x( 'We', 'Wednesday abbreviation', 'business-profile' ),
368
+ 'thursday' => _x( 'Th', 'Thursday abbreviation', 'business-profile' ),
369
+ 'friday' => _x( 'Fr', 'Friday abbreviation', 'business-profile' ),
370
+ 'saturday' => _x( 'Sa', 'Saturday abbreviation', 'business-profile' ),
371
+ 'sunday' => _x( 'Su', 'Sunday abbreviation', 'business-profile' ),
372
+ ),
373
+ 'time_format' => _x( 'h:i A', 'Time format displayed in the opening hours setting panel in your admin area. Must match formatting rules at http://amsul.ca/pickadate.js/time.htm#formats', 'business-profile' ),
374
+ 'date_format' => _x( 'mmmm d, yyyy', 'Date format displayed in the opening hours setting panel in your admin area. Must match formatting rules at http://amsul.ca/pickadate.js/date.htm#formatting-rules', 'business-profile' ),
375
+ 'disable_weeks' => true,
376
+ 'disable_date' => true,
377
+ 'strings' => array(
378
+ 'add_rule' => __( 'Add another opening time', 'business-profile' ),
379
+ 'weekly' => _x( 'Weekly', 'Format of a scheduling rule', 'business-profile' ),
380
+ 'monthly' => _x( 'Monthly', 'Format of a scheduling rule', 'business-profile' ),
381
+ 'date' => _x( 'Date', 'Format of a scheduling rule', 'business-profile' ),
382
+ 'weekdays' => _x( 'Days of the week', 'Label for selecting days of the week in a scheduling rule', 'business-profile' ),
383
+ 'month_weeks' => _x( 'Weeks of the month', 'Label for selecting weeks of the month in a scheduling rule', 'business-profile' ),
384
+ 'date_label' => _x( 'Date', 'Label to select a date for a scheduling rule', 'business-profile' ),
385
+ 'time_label' => _x( 'Time', 'Label to select a time slot for a scheduling rule', 'business-profile' ),
386
+ 'allday' => _x( 'All day', 'Label to set a scheduling rule to last all day', 'business-profile' ),
387
+ 'start' => _x( 'Start', 'Label for the starting time of a scheduling rule', 'business-profile' ),
388
+ 'end' => _x( 'End', 'Label for the ending time of a scheduling rule', 'business-profile' ),
389
+ 'set_time_prompt' => _x( 'All day long. Want to %sset a time slot%s?', 'Prompt displayed when a scheduling rule is set without any time restrictions', 'business-profile' ),
390
+ 'toggle' => _x( 'Open and close this rule', 'Toggle a scheduling rule open and closed', 'business-profile' ),
391
+ 'delete' => _x( 'Delete rule', 'Delete a scheduling rule', 'business-profile' ),
392
+ 'delete_schedule' => __( 'Delete scheduling rule', 'business-profile' ),
393
+ 'never' => _x( 'Never', 'Brief default description of a scheduling rule when no weekdays or weeks are included in the rule', 'business-profile' ),
394
+ 'weekly_always' => _x( 'Every day', 'Brief default description of a scheduling rule when all the weekdays/weeks are included in the rule', 'business-profile' ),
395
+ 'monthly_weekdays' => _x( '%s on the %s week of the month', 'Brief default description of a scheduling rule when some weekdays are included on only some weeks of the month. %s should be left alone and will be replaced by a comma-separated list of days and weeks in the following format: M, T, W on the first, second week of the month', 'business-profile' ),
396
+ 'monthly_weeks' => _x( '%s week of the month', 'Brief default description of a scheduling rule when some weeks of the month are included but all or no weekdays are selected. %s should be left alone and will be replaced by a comma-separated list of weeks in the following format: First, second week of the month', 'business-profile' ),
397
+ 'all_day' => _x( 'All day', 'Brief default description of a scheduling rule when no times are set', 'business-profile' ),
398
+ 'before' => _x( 'Ends at', 'Brief default description of a scheduling rule when an end time is set but no start time. If the end time is 6pm, it will read: Ends at 6pm', 'business-profile' ),
399
+ 'after' => _x( 'Starts at', 'Brief default description of a scheduling rule when a start time is set but no end time. If the start time is 6pm, it will read: Starts at 6pm', 'business-profile' ),
400
+ 'separator' => _x( '&mdash;', 'Separator between times of a scheduling rule', 'business-profile' ),
401
+ ),
402
+ )
403
+ );
404
+
405
+ $sap->add_section(
406
+ 'bpfwp-settings',
407
+ array(
408
+ 'id' => 'bpfwp-locations',
409
+ 'title' => __( 'Multiple Locations', 'business-profile' ),
410
+ )
411
+ );
412
+
413
+ $sap->add_setting(
414
+ 'bpfwp-settings',
415
+ 'bpfwp-locations',
416
+ 'toggle',
417
+ array(
418
+ 'id' => 'multiple-locations',
419
+ 'title' => __( 'Multiple Locations', 'business-profile' ),
420
+ 'label' => __( 'Enable support for multiple business locations.', 'business-profile' ),
421
+ )
422
+ );
423
+
424
+ $sap = apply_filters( 'bpfwp_settings_page', $sap );
425
+
426
+ $sap->add_admin_menus();
427
+
428
+ }
429
+
430
+ /**
431
+ * Array of schema type options
432
+ *
433
+ * @since 1.1
434
+ * @access public
435
+ * @return array A filtered list of schema types.
436
+ */
437
+ public function get_schema_types() {
438
+ return apply_filters(
439
+ 'bp_schema_types',
440
+ array(
441
+ 'Organization' => 'Organization',
442
+ 'Corporation' => 'Corporation',
443
+ 'EducationalOrganization' => 'Educational Organization',
444
+ 'GovernmentOrganization' => 'Government Organization',
445
+ 'LocalBusiness' => 'Local Business',
446
+ 'AnimalShelter' => '- Animal Shelter',
447
+ 'AutomotiveBusiness' => '- Automotive Business',
448
+ 'ChildCare' => '- Child Care',
449
+ 'DryCleaningOrLaundry' => '- Dry Cleaning or Laundry',
450
+ 'EmergencyService' => '- Emergency Service',
451
+ 'EmploymentAgency' => '- Employment Agency',
452
+ 'EntertainmentBusiness' => '- Entertainment Business',
453
+ 'FinancialService' => '- Financial Service',
454
+ 'FoodEstablishment' => '- Food Establishment',
455
+ 'GovernmentOffice' => '- Government Office',
456
+ 'HealthAndBeautyBusiness' => '- Health and Beauty Business',
457
+ 'HomeAndConstructionBusiness' => '- Home and Construction Business',
458
+ 'InternetCafe' => '- Internet Cafe',
459
+ 'Library' => '- Library',
460
+ 'LodgingBusiness' => '- Lodging Business',
461
+ 'MedicalOrganization' => '- Medical Organization',
462
+ 'RadioStation' => '- Radio Station',
463
+ 'RealEstateAgent' => '- Real Estate Agent',
464
+ 'RecyclingCenter' => '- Recycling Center',
465
+ 'SelfStorage' => '- Self Storage',
466
+ 'SportsActivityLocation' => '- Sports Activity Location',
467
+ 'Store' => '- Store',
468
+ 'TouristInformationCenter' => '- Tourist Information Center',
469
+ 'TravelAgency' => '- Travel Agency',
470
+ 'NGO' => 'NGO',
471
+ 'PerformingGroup' => 'PerformingGroup',
472
+ 'SportsTeam' => 'SportsTeam',
473
+ )
474
+ );
475
+ }
476
+ }
477
+ endif;
includes/class-template-loader.php ADDED
@@ -0,0 +1,70 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Template Loader for Plugins based on the Gamajo Template Loader from Gary
4
+ * Jones. See https://github.com/GaryJones/Gamajo-Template-Loader
5
+ *
6
+ * @package BusinessProfile
7
+ * @copyright Copyright (c) 2016, Theme of the Crop
8
+ * @license GPL-2.0+
9
+ * @since 1.1
10
+ */
11
+
12
+ include_once( BPFWP_PLUGIN_DIR . '/lib/class-gamajo-template-loader.php' );
13
+
14
+ /**
15
+ * Template loader.
16
+ *
17
+ * Originally based on functions in Easy Digital Downloads (thanks Pippin!).
18
+ *
19
+ * When using in a plugin, create a new class that extends this one and just overrides the properties.
20
+ *
21
+ * @package Gamajo_Template_Loader
22
+ * @author Gary Jones
23
+ */
24
+ class bpfwpTemplateLoader extends Bpfwp_Gamajo_Template_Loader {
25
+ /**
26
+ * Prefix for filter names.
27
+ *
28
+ * @since 1.0.0
29
+ * @access protected
30
+ * @var string
31
+ */
32
+ protected $filter_prefix = 'bpfwp';
33
+
34
+ /**
35
+ * Directory name where custom templates for this plugin should be found in the theme.
36
+ *
37
+ * For example: 'your-plugin-templates'.
38
+ *
39
+ * @since 1.0.0
40
+ * @access protected
41
+ * @var string
42
+ */
43
+ protected $theme_template_directory = 'business-profile-templates';
44
+
45
+ /**
46
+ * Reference to the root directory path of this plugin.
47
+ *
48
+ * Can either be a defined constant, or a relative reference from where the subclass lives.
49
+ *
50
+ * e.g. YOUR_PLUGIN_TEMPLATE or plugin_dir_path( dirname( __FILE__ ) ); etc.
51
+ *
52
+ * @since 1.0.0
53
+ * @access protected
54
+ * @var string
55
+ */
56
+ protected $plugin_directory = BPFWP_PLUGIN_DIR;
57
+
58
+ /**
59
+ * Directory name where templates are found in this plugin.
60
+ *
61
+ * Can either be a defined constant, or a relative reference from where the subclass lives.
62
+ *
63
+ * e.g. 'templates' or 'includes/templates', etc.
64
+ *
65
+ * @since 1.1.0
66
+ * @access protected
67
+ * @var string
68
+ */
69
+ protected $plugin_template_directory = 'templates';
70
+ }
includes/deprecated/class-integrations.php ADDED
@@ -0,0 +1,179 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Initialize third-party integrations
4
+ *
5
+ * DEPRECATED in version 1.1
6
+ *
7
+ * This file loads and runs code to help the theme that can be found in
8
+ * wp-content/themes/plate-up/includes. This code is separated from the normal
9
+ * functions.php file to make that file easier to read. Ideally, all code that
10
+ * is typically customized by users will be accessible through functions.php.
11
+ * The code that is loaded here should only pertain to more advanced features
12
+ * and functions that few users will ever touch if they are using this theme.
13
+ *
14
+ * @package BusinessProfile
15
+ * @copyright Copyright (c) 2016, Theme of the Crop
16
+ * @license GPL-2.0+
17
+ * @since 0.0.1
18
+ */
19
+
20
+ defined( 'ABSPATH' ) || exit;
21
+
22
+ if ( ! class_exists( 'bpfwpIntegrations', false ) ) :
23
+
24
+ /**
25
+ * Deprecated 3rd party integrations class.
26
+ *
27
+ * @since 0.0.1
28
+ * @deprecated 1.1
29
+ */
30
+ class bpfwpIntegrations {
31
+
32
+ /**
33
+ * Initialize the class and register hooks.
34
+ *
35
+ * @since 0.0.1
36
+ * @access public
37
+ * @return void
38
+ */
39
+ public function __construct() {
40
+ add_action( 'plugins_loaded', array( $this, 'plugins_loaded' ) );
41
+ }
42
+
43
+ /**
44
+ * Integrations run after the plugins are loaded
45
+ *
46
+ * @since 0.0.1
47
+ * @access public
48
+ */
49
+ public function plugins_loaded() {
50
+
51
+ // Restaurant Reservations handles the integration from v1.6+.
52
+ // This code is deprecated but will load if Restaurant
53
+ // Reservations is active but below v1.6. The RTB_VERSION constant
54
+ // was introduced in v1.6.
55
+ if ( defined( 'RTB_PLUGIN_DIR' ) && ! defined( 'RTB_VERSION' ) ) {
56
+
57
+ // Add default setting for booking link to template function/shortcode.
58
+ add_filter( 'bpfwp_default_display_settings', array( $this, 'bpwfp_booking_link_default' ) );
59
+
60
+ // Add the callback to print the booking link.
61
+ add_filter( 'bpwfwp_component_callbacks', array( $this, 'bpfwp_booking_link_callback' ) );
62
+
63
+ // Add display toggle for the booking link to the widget options.
64
+ add_filter( 'bpfwp_widget_display_toggles', array( $this, 'bpfwp_booking_link_widget_option' ) );
65
+
66
+ }
67
+ }
68
+
69
+ /**
70
+ * Add default setting for booking link to template function/shortcode
71
+ * Restaurant Reservations plugin
72
+ *
73
+ * @since 0.0.1
74
+ * @access public
75
+ * @param array $defaults The booking link defaults.
76
+ * @return array $defaults The modified booking link defaults.
77
+ */
78
+ public function bpwfp_booking_link_default( $defaults ) {
79
+
80
+ $defaults['show_booking_link'] = true;
81
+
82
+ return $defaults;
83
+ }
84
+
85
+ /**
86
+ * Add the callback to print the booking link
87
+ * Restaurant Reservations plugin
88
+ *
89
+ * @since 0.0.1
90
+ * @access public
91
+ * @param array $data The booking link data.
92
+ * @return array $data The modified booking link data.
93
+ */
94
+ public function bpfwp_booking_link_callback( $data ) {
95
+
96
+ global $rtb_controller;
97
+ $booking_page = $rtb_controller->settings->get_setting( 'booking-page' );
98
+
99
+ if ( ! empty( $booking_page ) ) {
100
+
101
+ // Place the link at the end of other short links if they're
102
+ // displayed.
103
+ if ( isset( $data['contact'] ) ) {
104
+ $pos = array_search( 'contact', array_keys( $data ) );
105
+ } elseif ( isset( $data['phone'] ) ) {
106
+ $pos = array_search( 'phone', array_keys( $data ) );
107
+ } elseif ( isset( $data['address'] ) ) {
108
+ $pos = array_search( 'address', array_keys( $data ) );
109
+ }
110
+
111
+ if ( ! empty( $pos ) ) {
112
+ $a = array_slice( $data, 0, $pos );
113
+ $b = array_slice( $data, $pos );
114
+ $data = array_merge( $a, array( 'booking_page' => array( $this, 'bpfwp_print_booking_link' ) ), $b );
115
+ } else {
116
+ // If no short links are being displayed, just add it to the bottom.
117
+ $data['booking_page'] = array( $this, 'bpfwp_print_booking_link' );
118
+ }
119
+ }
120
+
121
+ return $data;
122
+ }
123
+
124
+ /**
125
+ * Print the booking link from the Restaurant Reservations plugin.
126
+ *
127
+ * @since 0.0.1
128
+ * @access public
129
+ * @param string $location The location associated with the booking link.
130
+ * @return void
131
+ */
132
+ public function bpfwp_print_booking_link( $location = false ) {
133
+
134
+ global $bpfwp_controller;
135
+ global $rtb_controller;
136
+
137
+ $booking_page = $rtb_controller->settings->get_setting( 'booking-page' );
138
+
139
+ if ( $location && get_post_meta( $location, 'rtb_append_booking_form', true ) ) {
140
+ $booking_page = $location;
141
+ }
142
+
143
+ if ( bpfwp_get_display( 'show_booking_link' ) ) :
144
+ global $rtb_controller;
145
+ ?>
146
+ <div class="bp-booking">
147
+ <a href="<?php echo get_permalink( $booking_page ); ?>"><?php _e( 'Book a table', 'business-profile' ); ?></a>
148
+ </div>
149
+ <?php
150
+ endif;
151
+ }
152
+
153
+ /**
154
+ * Add the booking page display option to the widget options
155
+ * Restaurant Reservations plugin
156
+ *
157
+ * @since 0.0.1
158
+ * @access public
159
+ * @param array $toggles The toggle options for the widget.
160
+ * @return array $toggles The modified toggle options for the widget.
161
+ */
162
+ public function bpfwp_booking_link_widget_option( $toggles ) {
163
+
164
+ // Place the option below the contact option.
165
+ $pos = array_search( 'show_contact', array_keys( $toggles ) );
166
+
167
+ if ( ! empty( $pos ) ) {
168
+ $a = array_slice( $toggles, 0, $pos );
169
+ $b = array_slice( $toggles, $pos );
170
+ $toggles = array_merge( $a, array( 'show_booking_link' => __( 'Show book a table link', 'business-profile' ) ) , $b );
171
+ } else {
172
+ // If no short links are being displayed, just add it to the bottom.
173
+ $toggles['show_booking_link'] = __( 'Show book a table link', 'business-profile' );
174
+ }
175
+
176
+ return $toggles;
177
+ }
178
+ }
179
+ endif;
includes/template-functions.php CHANGED
@@ -1,466 +1,613 @@
1
  <?php
2
  /**
3
- * Template functions for rendering contact cards
 
 
 
 
 
4
  */
5
 
6
- /**
7
- * Print a contact card and add a shortcode
8
- * @since 0.0.1
9
- */
10
- if ( !function_exists( 'bpwfwp_print_contact_card' ) ) {
11
- function bpwfwp_print_contact_card( $args = array() ) {
12
-
13
- // Define shortcode attributes
14
- $defaults = array(
15
- 'show_name' => true,
16
- 'show_address' => true,
17
- 'show_get_directions' => true,
18
- 'show_phone' => true,
19
- 'show_contact' => true,
20
- 'show_opening_hours' => true,
21
- 'show_opening_hours_brief' => false,
22
- 'show_map' => true,
23
- );
24
-
25
- $defaults = apply_filters( 'bpwfp_contact_card_defaults', $defaults );
26
-
27
- global $bpfwp_controller;
28
- $bpfwp_controller->display_settings = shortcode_atts( $defaults, $args, 'contact-card' );
29
-
30
- // Setup components and callback functions to render them
31
- $data = array();
32
-
33
- if ( $bpfwp_controller->settings->get_setting( 'name' ) ) {
34
- $data['name'] = 'bpwfwp_print_name';
35
- }
36
-
37
- if ( $bpfwp_controller->settings->get_setting( 'address' ) ) {
38
- $data['address'] = 'bpwfwp_print_address';
39
  }
 
40
 
41
- if ( $bpfwp_controller->settings->get_setting( 'phone' ) ) {
42
- $data['phone'] = 'bpwfwp_print_phone';
43
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
44
 
45
- if ( $bpfwp_controller->display_settings['show_contact'] &&
46
- ( $bpfwp_controller->settings->get_setting( 'contact-email' ) || $bpfwp_controller->settings->get_setting( 'contact-page' ) ) ) {
47
- $data['contact'] = 'bpwfwp_print_contact';
48
  }
 
49
 
50
- if ( $bpfwp_controller->settings->get_setting( 'opening-hours' ) ) {
51
- $data['opening_hours'] = 'bpwfwp_print_opening_hours';
52
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
53
 
54
- if ( $bpfwp_controller->display_settings['show_map'] && $bpfwp_controller->settings->get_setting( 'address' ) ) {
55
- $data['map'] = 'bpwfwp_print_map';
56
  }
 
57
 
58
- $data = apply_filters( 'bpwfwp_component_callbacks', $data );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
59
 
 
 
 
60
 
61
- if ( apply_filters( 'bpfwp-load-frontend-assets', true ) ) {
62
- wp_enqueue_style( 'dashicons' );
63
- wp_enqueue_style( 'bpfwp-default' );
64
- }
 
65
 
66
- ob_start();
67
- ?>
68
 
69
- <address class="bp-contact-card" itemscope itemtype="http://schema.org/<?php echo $bpfwp_controller->settings->get_setting( 'schema_type' ); ?>">
70
- <?php foreach ( $data as $data => $callback ) { call_user_func( $callback ); } ?>
71
- </address>
72
 
73
- <?php
74
- $output = ob_get_clean();
75
 
76
- return apply_filters( 'bpwfwp_contact_card_output', $output );
77
- }
78
- if ( !shortcode_exists( 'contact-card' ) ) {
79
- add_shortcode( 'contact-card', 'bpwfwp_print_contact_card' );
80
  }
81
- } // endif;
82
 
83
- /**
84
- * Print the name
85
- * @since 0.0.1
86
- */
87
- if ( !function_exists( 'bpwfwp_print_name' ) ) {
88
- function bpwfwp_print_name() {
89
-
90
- global $bpfwp_controller;
 
 
 
 
 
 
 
 
91
 
92
- if ( $bpfwp_controller->display_settings['show_name'] ) :
93
- ?>
94
- <div class="bp-name" itemprop="name">
95
- <?php echo esc_attr( $bpfwp_controller->settings->get_setting( 'name' ) ); ?>
96
- </div>
97
 
98
- <?php else : ?>
99
- <meta itemprop="name" content="<?php echo esc_attr( $bpfwp_controller->settings->get_setting( 'name' ) ); ?>">
100
 
101
- <?php endif; ?>
 
 
102
 
103
- <meta itemprop="description" content="<?php echo esc_attr( get_bloginfo( 'description' ) ) ?>">
104
- <meta itemprop="url" content="<?php echo esc_attr( get_bloginfo( 'url' ) ); ?>">
105
 
106
- <?php
 
107
  }
108
- } // endif;
109
-
110
- /**
111
- * Print the address with a get directions link to Google Maps
112
- * @since 0.0.1
113
- */
114
- if ( !function_exists( 'bpwfwp_print_address' ) ) {
115
- function bpwfwp_print_address() {
116
 
117
- global $bpfwp_controller;
118
-
119
- $address = $bpfwp_controller->settings->get_setting( 'address' );
120
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
121
 
122
- <meta itemprop="address" content="<?php echo esc_attr( $address['text'] ); ?>">
123
 
124
- <?php if ( $bpfwp_controller->display_settings['show_address'] ) : ?>
125
- <div class="bp-address">
126
- <?php echo nl2br( $address['text'] ); ?>
127
- </div>
128
- <?php endif; ?>
129
 
130
- <?php if ( $bpfwp_controller->display_settings['show_get_directions'] ) : ?>
131
- <div class="bp-directions">
132
- <a href="//maps.google.com/maps?saddr=current+location&daddr=<?php echo urlencode( esc_attr( $address['text'] ) ); ?>" target="_blank"><?php _e( 'Get directions', 'business-profile' ); ?></a>
133
- </div>
134
- <?php endif;
135
 
 
136
  }
137
- } // endif;
138
-
139
- /**
140
- * Print the phone number
141
- * @since 0.0.1
142
- */
143
- if ( !function_exists( 'bpwfwp_print_phone' ) ) {
144
- function bpwfwp_print_phone() {
145
 
146
- global $bpfwp_controller;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
147
 
148
- if ( $bpfwp_controller->display_settings['show_phone'] ) :
149
- ?>
150
 
151
- <div class="bp-phone" itemprop="telephone">
152
- <?php echo $bpfwp_controller->settings->get_setting( 'phone' ); ?>
153
- </div>
154
 
155
- <?php else : ?>
156
- <meta itemprop="telephone" content="<?php echo esc_attr( $bpfwp_controller->settings->get_setting( 'phone' ) ); ?>">
157
 
158
- <?php endif;
 
159
  }
160
- } // endif;
161
-
162
- /**
163
- * Print the contact link
164
- * @since 0.0.1
165
- */
166
- if ( !function_exists( 'bpwfwp_print_contact' ) ) {
167
- function bpwfwp_print_contact() {
168
 
169
- global $bpfwp_controller;
 
 
 
 
 
 
 
 
 
170
 
171
- $email = $bpfwp_controller->settings->get_setting( 'contact-email' );
172
- if ( !empty( $email ) ) :
173
- $antispam_email = antispambot( $email );
174
- ?>
175
 
176
- <div class="bp-contact bp-contact-email" itemprop="email" content="<?php echo esc_attr( $antispam_email ); ?>">
177
- <a href="mailto:<?php echo esc_attr( $antispam_email ); ?>"><?php echo $antispam_email; ?></a>
178
- </div>
179
 
180
- <?php
181
- return;
182
- endif;
183
 
184
- $contact = $bpfwp_controller->settings->get_setting( 'contact-page' );
185
- if ( !empty( $contact ) ) :
186
- ?>
187
 
188
- <div class="bp-contact bp-contact-page" itemprop="ContactPoint" itemscope itemtype="http://schema.org/ContactPoint">
189
- <meta itemprop="contactType" content="customer support">
190
- <a href="<?php echo get_permalink( $contact ); ?>" itemprop="url" content="<?php echo esc_attr( get_permalink( $contact ) ); ?>"><?php _e( 'Contact', 'business-profile' ); ?></a>
191
- </div>
192
 
193
- <?php endif;
194
-
195
- }
196
- } // endif;
197
 
198
- /**
199
- * Print the opening hours
200
- * @since 0.0.1
201
- */
202
- if ( !function_exists( 'bpwfwp_print_opening_hours' ) ) {
203
- function bpwfwp_print_opening_hours() {
204
 
205
- global $bpfwp_controller;
 
 
 
206
 
207
- $weekdays_schema = array(
208
- 'monday' => 'Mo',
209
- 'tuesday' => 'Tu',
210
- 'wednesday' => 'We',
211
- 'thursday' => 'Th',
212
- 'friday' => 'Fr',
213
- 'saturday' => 'Sa',
214
- 'sunday' => 'Su',
215
- );
216
 
217
- $hours = $bpfwp_controller->settings->get_setting( 'opening-hours' );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
218
 
219
- // Output proper schema.org format
220
- foreach( $hours as $slot ) {
221
 
222
- // Skip this entry if no weekdays are set
223
- if ( empty( $slot['weekdays'] ) ) {
224
- continue;
225
  }
226
 
227
- $days = array();
228
- foreach( $slot['weekdays'] as $day => $val ) {
229
- $days[] = $weekdays_schema[ $day ];
230
- }
231
- $string = !empty( $days ) ? join( ',', $days ) : '';
232
 
233
- if ( !empty( $string) && !empty( $slot['time'] ) ) {
234
 
235
- if ( empty( $slot['time']['start'] ) ) {
236
- $start = '00:00';
237
- } else {
238
- $start = trim( substr( $slot['time']['start'], 0, -2 ) );
239
- if ( substr( $slot['time']['start'], -2 ) == 'PM' && $start !== '12:00' ) {
240
- $split = explode( ':', $start );
241
- $split[0] += 12;
242
- $start = join( ':', $split );
243
- }
244
- if ( substr( $slot['time']['start'], -2 ) == 'AM' && $start == '12:00' ) {
245
- $start = '00:00';
246
- }
247
- }
248
 
249
- if ( empty( $slot['time']['end'] ) ) {
250
- $end = '24:00';
251
- } else {
252
- $end = trim( substr( $slot['time']['end'], 0, -2 ) );
253
- if ( substr( $slot['time']['end'], -2 ) == 'PM' ) {
254
- $split = explode( ':', $end );
255
- $split[0] += 12;
256
- $end = join( ':', $split );
257
- }
258
- if ( !empty( $slot['time']['start'] ) && substr( $slot['time']['start'], -2 ) == 'AM' && $start == '12:00' ) {
259
- $end = '24:00';
260
  }
261
- }
262
 
263
- $string .= ' ' . $start . '-' . $end;
264
- }
265
- echo '<meta itemprop="openingHours" content="' . esc_attr( $string ) . '">';
266
- }
 
 
 
 
 
 
 
 
 
 
267
 
268
- // Output display format
269
- if ( !$bpfwp_controller->display_settings['show_opening_hours'] ) {
270
- return;
271
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
272
 
273
- if ( $bpfwp_controller->display_settings['show_opening_hours_brief'] ) :
274
- ?>
275
 
276
- <div class="bp-opening-hours-brief">
 
277
 
278
- <?php
279
- $slots = array();
280
- foreach( $hours as $slot ) {
281
 
282
- // Skip this entry if no weekdays are set
283
- if ( empty( $slot['weekdays'] ) ) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
284
  continue;
285
  }
286
 
287
- $days = array();
288
- $weekdays_i18n = array(
289
- 'monday' => esc_html__( 'Mo', 'business-profile' ),
290
- 'tuesday' => esc_html__( 'Tu', 'business-profile' ),
291
- 'wednesday' => esc_html__( 'We', 'business-profile' ),
292
- 'thursday' => esc_html__( 'Th', 'business-profile' ),
293
- 'friday' => esc_html__( 'Fr', 'business-profile' ),
294
- 'saturday' => esc_html__( 'Sa', 'business-profile' ),
295
- 'sunday' => esc_html__( 'Su', 'business-profile' ),
296
- );
297
- foreach( $slot['weekdays'] as $day => $val ) {
298
- $days[] = $weekdays_i18n[ $day ];
299
- }
300
- $days_string = !empty( $days ) ? join( _x( ',', 'Separator between days of the week when displaying opening hours in brief. Example: Mo,Tu,We', 'business-profile' ), $days ) : '';
301
 
302
- if ( empty( $slot['time'] ) ) {
303
- $string = sprintf( _x( '%s all day', 'Brief opening hours description which lists days_strings when open all day. Example: Mo,Tu,We all day', 'business-profile' ), $days_string );
304
  } else {
305
- unset( $start );
306
- unset( $end );
307
- if ( !empty( $slot['time']['start'] ) ) {
308
- $start = new DateTime( $slot['time']['start'] );
309
  }
310
- if ( !empty( $slot['time']['end'] ) ) {
311
- $end = new DateTime( $slot['time']['end'] );
312
  }
313
 
314
  if ( empty( $start ) ) {
315
- $string = sprintf( _x( '%s open until %s', 'Brief opening hours description which lists the days followed by the closing time. Example: Mo,Tu,We open until 9:00pm', 'business-profile' ), $days_string, $end->format( get_option( 'time_format' ) ) );
316
  } elseif ( empty( $end ) ) {
317
- $string = sprintf( _x( '%s open from %s', 'Brief opening hours description which lists the days followed by the opening time. Example: Mo,Tu,We open from 9:00am', 'business-profile' ), $days_string, $start->format( get_option( 'time_format' ) ) );
318
  } else {
319
- $string = sprintf( _x( '%s %s-%s', 'Brief opening hours description which lists the days followed by the opening and closing times. Example: Mo,Tu,We 9:00am-5:00pm', 'business-profile' ), $days_string, $start->format( get_option( 'time_format' ) ), $end->format( get_option( 'time_format' ) ) );
320
  }
321
  }
322
 
323
- $slots[] = $string;
324
- }
325
-
326
- echo join( _x( '; ', 'Separator between multiple opening times in the brief opening hours. Example: Mo,We 9:00 AM - 5:00 PM; Tu,Th 10:00 AM - 5:00 PM', 'business-profile' ), $slots );
327
- ?>
328
 
329
- </div>
330
-
331
- <?php
332
- return;
333
- endif; // brief opening hours
334
-
335
- $weekdays_display = array(
336
- 'monday' => __( 'Monday' ),
337
- 'tuesday' => __( 'Tuesday' ),
338
- 'wednesday' => __( 'Wednesday' ),
339
- 'thursday' => __( 'Thursday' ),
340
- 'friday' => __( 'Friday' ),
341
- 'saturday' => __( 'Saturday' ),
342
- 'sunday' => __( 'Sunday' ),
343
- );
344
-
345
- $weekdays = array();
346
- foreach( $hours as $rule ) {
347
 
348
- // Skip this entry if no weekdays are set
349
- if ( empty( $rule['weekdays'] ) ) {
350
- continue;
351
  }
352
 
353
- if ( empty( $rule['time'] ) ) {
354
- $time = __( 'Open', 'business-profile' );
355
-
356
- } else {
357
 
358
- if ( !empty( $rule['time']['start'] ) ) {
359
- $start = new DateTime( $rule['time']['start'] );
360
- }
361
- if ( !empty( $rule['time']['end'] ) ) {
362
- $end = new DateTime( $rule['time']['end'] );
 
 
 
363
  }
364
 
365
- if ( empty( $start ) ) {
366
- $time = __( 'Open until ', 'business-profile' ) . $end->format( get_option( 'time_format' ) );
367
- } elseif ( empty( $end ) ) {
368
- $time = __( 'Open from ', 'business-profile' ) . $start->format( get_option( 'time_format' ) );
 
 
 
 
 
 
369
  } else {
370
- $time = $start->format( get_option( 'time_format' ) ) . _x( '-', 'Separator between opening and closing times. Example: 9:00am-5:00pm', 'business-profile' ) . $end->format( get_option( 'time_format' ) );
371
  }
372
  }
 
 
373
 
374
- foreach( $rule['weekdays'] as $day => $val ) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
375
 
376
- if ( !array_key_exists( $day, $weekdays ) ) {
377
- $weekdays[$day] = array();
 
378
  }
 
379
 
380
- $weekdays[$day][] = $time;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
381
  }
382
  }
 
383
 
384
- if ( count( $weekdays ) ) :
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
385
 
386
- // Order the weekdays and add any missing days as "closed"
387
- $weekdays_ordered = array();
388
- foreach( $weekdays_display as $slug => $name ) {
389
- if ( !array_key_exists( $slug, $weekdays ) ) {
390
- $weekdays_ordered[$slug] = array( __( 'Closed', 'business-profile' ) );
391
- } else {
392
- $weekdays_ordered[$slug] = $weekdays[$slug];
393
- }
 
 
 
 
 
 
 
 
394
  }
395
- ?>
396
-
397
- <div class="bp-opening-hours">
398
- <span class="bp-title"><?php _e( 'Opening Hours', 'business-profile' ); ?></span>
399
- <?php foreach ( $weekdays_ordered as $weekday => $times ) : ?>
400
- <div class="bp-weekday">
401
- <span class="bp-weekday-name bp-weekday-<?php echo $weekday; ?>"><?php echo $weekdays_display[$weekday]; ?></span>
402
- <span class="bp-times">
403
- <?php foreach ( $times as $time ) : ?>
404
- <span class="bp-time"><?php echo $time; ?></span>
405
- <?php endforeach; ?>
406
- </span>
407
- </div>
408
- <?php endforeach; ?>
409
- </div>
410
 
411
- <?php
412
- endif;
413
- }
414
- } // endif;
415
 
416
- /**
417
- * Print a map to the address
418
- * @since 0.0.1
419
- */
420
- if ( !function_exists( 'bpwfwp_print_map' ) ) {
421
- function bpwfwp_print_map() {
422
-
423
- global $bpfwp_controller;
424
-
425
- $address = $bpfwp_controller->settings->get_setting( 'address' );
426
-
427
- wp_enqueue_script( 'bpfwp-map' );
428
- wp_localize_script(
429
- 'bpfwp-map',
430
- 'bpfwp_map',
431
- array(
432
- // Override loading and intialization of Google Maps api
433
- 'autoload_google_maps' => apply_filters( 'bpfwp_autoload_google_maps', true ),
434
- 'map_options' => apply_filters( 'bpfwp_google_map_options', array() ),
435
- 'strings' => array(
436
- 'get_directions' => __( 'Get directions', 'business-profile' ),
437
- )
438
- )
439
- );
440
 
441
- global $bpfwp_map_ids;
442
- if ( empty( $bpfwp_map_ids ) ) {
443
- $bpfwp_map_ids = array();
444
- }
445
 
446
- $id = count( $bpfwp_map_ids );
447
- $bpfwp_map_ids[] = $id;
 
 
448
 
 
 
 
 
449
 
450
- $attr = '';
451
 
452
- $phone = $bpfwp_controller->settings->get_setting( 'phone' );
453
- if ( !empty( $phone ) ) {
454
- $attr .= ' data-phone="' . esc_attr( $phone ) . '"';
455
  }
 
456
 
457
- if ( !empty( $address['lat'] ) && !empty( $address['lon'] ) ) {
458
- $attr .= ' data-lat="' . esc_attr( $address['lat'] ) . '" data-lon="' . esc_attr( $address['lon'] ) . '"';
459
- }
460
- ?>
 
 
 
 
 
461
 
462
- <div id="bp-map-<?php echo $id; ?>" class="bp-map" itemprop="map" data-name="<?php echo esc_attr( $bpfwp_controller->settings->get_setting( 'name' ) ); ?>" data-address="<?php echo esc_attr( $address['text'] ); ?>"<?php echo $attr; ?>></div>
 
 
 
 
463
 
464
- <?php
 
 
 
 
 
465
  }
466
- } // endif;
1
  <?php
2
  /**
3
+ * Template functions for rendering contact cards.
4
+ *
5
+ * @package BusinessProfile
6
+ * @copyright Copyright (c) 2016, Theme of the Crop
7
+ * @license GPL-2.0+
8
+ * @since 0.0.1
9
  */
10
 
11
+ if ( ! function_exists( 'bpfwp_setting' ) ) {
12
+ /**
13
+ * Retrieve the value of any stored setting
14
+ *
15
+ * A wrapper for $bpfw_controller->settings->get_setting() that should be
16
+ * used to access any data for the global location or one of the location
17
+ * custom posts.
18
+ *
19
+ * @since 1.1
20
+ * @access public
21
+ * @param string $setting The setting to retrieve.
22
+ * @param string $location The location associated with the setting.
23
+ * @return mixed A setting based on the key provided.
24
+ */
25
+ function bpfwp_setting( $setting, $location = false ) {
26
+ global $bpfwp_controller;
27
+ return $bpfwp_controller->settings->get_setting( $setting, $location );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
28
  }
29
+ }
30
 
31
+ if ( ! function_exists( 'bpfwp_get_display' ) ) {
32
+ /**
33
+ * A helper function to check if a setting should be displayed visually or
34
+ * added as metadata
35
+ *
36
+ * @since 1.1
37
+ * @access public
38
+ * @param string $setting The setting to retrieve.
39
+ * @return mixed A setting based on the key provided.
40
+ */
41
+ function bpfwp_get_display( $setting ) {
42
+
43
+ global $bpfwp_controller;
44
+
45
+ if ( empty( $bpfwp_controller->display_settings ) ) {
46
+ $bpfwp_controller->display_settings = $bpfwp_controller->settings->get_default_display_settings();
47
+ }
48
 
49
+ return isset( $bpfwp_controller->display_settings[ $setting ] ) ? $bpfwp_controller->display_settings[ $setting ] : false;
 
 
50
  }
51
+ }
52
 
53
+ if ( ! function_exists( 'bpfwp_set_display' ) ) {
54
+ /**
55
+ * A helper function to set a setting's visibility on the fly
56
+ *
57
+ * These visibility flags are usually set when the shortcode or widget is
58
+ * loaded, or bpwfwp_print_contact_card() is called. This helper function
59
+ * makes it easy to set a flag if you're building your own template.
60
+ *
61
+ * @since 1.1
62
+ * @access public
63
+ * @param string $setting The setting to be changed.
64
+ * @param string $value The setting value to be used.
65
+ * @return void
66
+ */
67
+ function bpfwp_set_display( $setting, $value ) {
68
+
69
+ global $bpfwp_controller;
70
+
71
+ if ( empty( $bpfwp_controller->display_settings ) ) {
72
+ $bpfwp_controller->display_settings = $bpfwp_controller->settings->get_default_display_settings();
73
+ }
74
 
75
+ $bpfwp_controller->display_settings[ $setting ] = $value;
 
76
  }
77
+ }
78
 
79
+ if ( ! function_exists( 'bpwfwp_print_contact_card' ) ) {
80
+ /**
81
+ * Print a contact card and add a shortcode.
82
+ *
83
+ * @since 0.0.1
84
+ * @access public
85
+ * @param array $args Options for outputting the contact card.
86
+ * @return string Markup for displaying a contact card.
87
+ */
88
+ function bpwfwp_print_contact_card( $args = array() ) {
89
+
90
+ global $bpfwp_controller;
91
+
92
+ // Define shortcode attributes.
93
+ $bpfwp_controller->display_settings = shortcode_atts(
94
+ $bpfwp_controller->settings->get_default_display_settings(),
95
+ $args,
96
+ 'contact-card'
97
+ );
98
+
99
+ // Setup components and callback functions to render them.
100
+ $data = apply_filters(
101
+ 'bpwfwp_component_callbacks',
102
+ array(
103
+ 'name' => 'bpwfwp_print_name',
104
+ 'address' => 'bpwfwp_print_address',
105
+ 'phone' => 'bpwfwp_print_phone',
106
+ 'contact' => 'bpwfwp_print_contact',
107
+ 'opening_hours' => 'bpwfwp_print_opening_hours',
108
+ 'map' => 'bpwfwp_print_map',
109
+ 'parent_organization' => 'bpfwp_print_parent_organization',
110
+ )
111
+ );
112
+
113
+ if ( ! $bpfwp_controller->get_theme_support( 'disable_styles' ) ) {
114
+ /**
115
+ * Filter to override whether the frontend stylesheets are loaded.
116
+ *
117
+ * This is deprecated in favor of add_theme_support(). To prevent
118
+ * styles from being loaded, add the following to your theme:
119
+ *
120
+ * add_theme_support( 'business-profile', array( 'disable_styles' => true ) );
121
+ */
122
+ if ( apply_filters( 'bpfwp-load-frontend-assets', true ) ) {
123
+ wp_enqueue_style( 'dashicons' );
124
+ wp_enqueue_style( 'bpfwp-default' );
125
+ }
126
+ }
127
 
128
+ ob_start();
129
+ $template = new bpfwpTemplateLoader;
130
+ $template->set_template_data( $data );
131
 
132
+ if ( bpfwp_get_display( 'location' ) ) {
133
+ $template->get_template_part( 'contact-card', bpfwp_get_display( 'location' ) );
134
+ } else {
135
+ $template->get_template_part( 'contact-card' );
136
+ }
137
 
138
+ $output = ob_get_clean();
 
139
 
140
+ // Reset display settings.
141
+ $bpfwp_controller->display_settings = $bpfwp_controller->settings->get_default_display_settings();
 
142
 
143
+ return apply_filters( 'bpwfwp_contact_card_output', $output );
144
+ }
145
 
146
+ if ( ! shortcode_exists( 'contact-card' ) ) {
147
+ add_shortcode( 'contact-card', 'bpwfwp_print_contact_card' );
148
+ }
 
149
  }
 
150
 
151
+ if ( ! function_exists( 'bpwfwp_print_name' ) ) {
152
+ /**
153
+ * Print the name.
154
+ *
155
+ * @since 0.0.1
156
+ * @access public
157
+ * @param string $location The location associated with the name.
158
+ * @return void
159
+ */
160
+ function bpwfwp_print_name( $location = false ) {
161
+
162
+ if ( bpfwp_get_display( 'show_name' ) ) :
163
+ ?>
164
+ <div class="bp-name" itemprop="name">
165
+ <?php echo esc_attr( bpfwp_setting( 'name', $location ) ); ?>
166
+ </div>
167
 
168
+ <?php else : ?>
169
+ <meta itemprop="name" content="<?php echo esc_attr( bpfwp_setting( 'name', $location ) ); ?>">
 
 
 
170
 
171
+ <?php endif; ?>
 
172
 
173
+ <?php if ( empty( $location ) ) : ?>
174
+ <meta itemprop="description" content="<?php echo esc_attr( get_bloginfo( 'description' ) ) ?>">
175
+ <meta itemprop="url" content="<?php echo esc_url( get_bloginfo( 'url' ) ); ?>">
176
 
177
+ <?php else : ?>
178
+ <meta itemprop="url" content="<?php echo esc_url( get_permalink( $location ) ); ?>">
179
 
180
+ <?php endif;
181
+ }
182
  }
 
 
 
 
 
 
 
 
183
 
184
+ if ( ! function_exists( 'bpwfwp_print_address' ) ) {
185
+ /**
186
+ * Print the address with a get directions link to Google Maps.
187
+ *
188
+ * @since 0.0.1
189
+ * @access public
190
+ * @param string $location The location associated with the address.
191
+ * @return string|void Returns an empty string if no address exists.
192
+ */
193
+ function bpwfwp_print_address( $location = false ) {
194
+
195
+ $address = bpfwp_setting( 'address', $location );
196
+
197
+ if ( empty( $address['text'] ) ) {
198
+ return '';
199
+ }
200
+ ?>
201
 
202
+ <meta itemprop="address" content="<?php echo esc_attr( $address['text'] ); ?>">
203
 
204
+ <?php if ( bpfwp_get_display( 'show_address' ) ) : ?>
205
+ <div class="bp-address">
206
+ <?php echo nl2br( $address['text'] ); ?>
207
+ </div>
208
+ <?php endif; ?>
209
 
210
+ <?php if ( bpfwp_get_display( 'show_get_directions' ) ) : ?>
211
+ <div class="bp-directions">
212
+ <a href="//maps.google.com/maps?saddr=current+location&daddr=<?php echo urlencode( esc_attr( $address['text'] ) ); ?>" target="_blank"><?php _e( 'Get directions', 'business-profile' ); ?></a>
213
+ </div>
214
+ <?php endif;
215
 
216
+ }
217
  }
 
 
 
 
 
 
 
 
218
 
219
+ if ( ! function_exists( 'bpwfwp_print_phone' ) ) {
220
+ /**
221
+ * Print the phone number.
222
+ *
223
+ * @since 0.0.1
224
+ * @access public
225
+ * @param string $location The location associated with the phone.
226
+ * @return string|void Returns an empty string if no phone exists.
227
+ */
228
+ function bpwfwp_print_phone( $location = false ) {
229
+
230
+ $phone = bpfwp_setting( 'phone', $location );
231
+
232
+ if ( empty( $phone ) ) {
233
+ return '';
234
+ }
235
 
236
+ if ( bpfwp_get_display( 'show_phone' ) ) :
237
+ ?>
238
 
239
+ <div class="bp-phone" itemprop="telephone">
240
+ <?php echo bpfwp_setting( 'phone', $location ); ?>
241
+ </div>
242
 
243
+ <?php else : ?>
244
+ <meta itemprop="telephone" content="<?php echo esc_attr( bpfwp_setting( 'phone', $location ) ); ?>">
245
 
246
+ <?php endif;
247
+ }
248
  }
 
 
 
 
 
 
 
 
249
 
250
+ if ( ! function_exists( 'bpwfwp_print_contact' ) ) {
251
+ /**
252
+ * Print the contact link.
253
+ *
254
+ * @since 0.0.1
255
+ * @access public
256
+ * @param string $location The location associated with the contact.
257
+ * @return string|void Returns an empty string if no contact exists.
258
+ */
259
+ function bpwfwp_print_contact( $location = false ) {
260
 
261
+ $email = bpfwp_setting( 'contact-email', $location );
262
+ if ( ! empty( $email ) ) :
263
+ $antispam_email = antispambot( $email );
 
264
 
265
+ if ( ! bpfwp_get_display( 'show_contact' ) ) :
266
+ ?>
267
+ <meta itemprop="email" content="<?php echo esc_attr( $antispam_email ); ?>">
268
 
269
+ <?php else : ?>
 
 
270
 
271
+ <div class="bp-contact bp-contact-email" itemprop="email" content="<?php echo esc_attr( $antispam_email ); ?>">
272
+ <a href="mailto:<?php echo esc_attr( $antispam_email ); ?>"><?php echo $antispam_email; ?></a>
273
+ </div>
274
 
275
+ <?php endif; ?>
 
 
 
276
 
277
+ <?php
278
+ return;
279
+ endif;
 
280
 
281
+ $contact = bpfwp_setting( 'contact-page', $location );
282
+ if ( ! empty( $contact ) && bpfwp_get_display( 'show_contact' ) ) :
283
+ ?>
 
 
 
284
 
285
+ <div class="bp-contact bp-contact-page" itemprop="ContactPoint" itemscope itemtype="http://schema.org/ContactPoint">
286
+ <meta itemprop="contactType" content="customer support">
287
+ <a href="<?php echo get_permalink( $contact ); ?>" itemprop="url" content="<?php echo esc_attr( get_permalink( $contact ) ); ?>"><?php _e( 'Contact', 'business-profile' ); ?></a>
288
+ </div>
289
 
290
+ <?php endif;
291
+ }
292
+ }
 
 
 
 
 
 
293
 
294
+ if ( ! function_exists( 'bpwfwp_print_opening_hours' ) ) {
295
+ /**
296
+ * Print the opening hours.
297
+ *
298
+ * @since 0.0.1
299
+ * @access public
300
+ * @param string $location The location associated with the hours.
301
+ * @return string|void Returns an empty string if no hours exist.
302
+ */
303
+ function bpwfwp_print_opening_hours( $location = false ) {
304
+
305
+ $hours = bpfwp_setting( 'opening-hours', $location );
306
+
307
+ if ( empty( $hours ) ) {
308
+ return '';
309
+ }
310
 
311
+ // Print the metatags with proper schema formatting.
312
+ bpfwp_print_opening_hours_metatag( $hours );
313
 
314
+ if ( ! bpfwp_get_display( 'show_opening_hours' ) ) {
315
+ return;
 
316
  }
317
 
318
+ // Output display format.
319
+ if ( bpfwp_get_display( 'show_opening_hours_brief' ) ) :
320
+ ?>
 
 
321
 
322
+ <div class="bp-opening-hours-brief">
323
 
324
+ <?php
325
+ $slots = array();
326
+ foreach ( $hours as $slot ) {
 
 
 
 
 
 
 
 
 
 
327
 
328
+ // Skip this entry if no weekdays are set.
329
+ if ( empty( $slot['weekdays'] ) ) {
330
+ continue;
 
 
 
 
 
 
 
 
331
  }
 
332
 
333
+ $days = array();
334
+ $weekdays_i18n = array(
335
+ 'monday' => esc_html__( 'Mo', 'business-profile' ),
336
+ 'tuesday' => esc_html__( 'Tu', 'business-profile' ),
337
+ 'wednesday' => esc_html__( 'We', 'business-profile' ),
338
+ 'thursday' => esc_html__( 'Th', 'business-profile' ),
339
+ 'friday' => esc_html__( 'Fr', 'business-profile' ),
340
+ 'saturday' => esc_html__( 'Sa', 'business-profile' ),
341
+ 'sunday' => esc_html__( 'Su', 'business-profile' ),
342
+ );
343
+ foreach ( $slot['weekdays'] as $day => $val ) {
344
+ $days[] = $weekdays_i18n[ $day ];
345
+ }
346
+ $days_string = ! empty( $days ) ? join( _x( ',', 'Separator between days of the week when displaying opening hours in brief. Example: Mo,Tu,We', 'business-profile' ), $days ) : '';
347
 
348
+ if ( empty( $slot['time'] ) ) {
349
+ $string = sprintf( _x( '%s all day', 'Brief opening hours description which lists days_strings when open all day. Example: Mo,Tu,We all day', 'business-profile' ), $days_string );
350
+ } else {
351
+ unset( $start );
352
+ unset( $end );
353
+ if ( ! empty( $slot['time']['start'] ) ) {
354
+ $start = new DateTime( $slot['time']['start'] );
355
+ }
356
+ if ( ! empty( $slot['time']['end'] ) ) {
357
+ $end = new DateTime( $slot['time']['end'] );
358
+ }
359
+
360
+ if ( empty( $start ) ) {
361
+ $string = sprintf( _x( '%s open until %s', 'Brief opening hours description which lists the days followed by the closing time. Example: Mo,Tu,We open until 9:00pm', 'business-profile' ), $days_string, $end->format( get_option( 'time_format' ) ) );
362
+ } elseif ( empty( $end ) ) {
363
+ $string = sprintf( _x( '%s open from %s', 'Brief opening hours description which lists the days followed by the opening time. Example: Mo,Tu,We open from 9:00am', 'business-profile' ), $days_string, $start->format( get_option( 'time_format' ) ) );
364
+ } else {
365
+ $string = sprintf( _x( '%s %s&thinsp;&ndash;&thinsp;%s', 'Brief opening hours description which lists the days followed by the opening and closing times. Example: Mo,Tu,We 9:00am&thinsp;&ndash;&thinsp;5:00pm', 'business-profile' ), $days_string, $start->format( get_option( 'time_format' ) ), $end->format( get_option( 'time_format' ) ) );
366
+ }
367
+ }
368
 
369
+ $slots[] = $string;
370
+ }
371
 
372
+ echo join( _x( '; ', 'Separator between multiple opening times in the brief opening hours. Example: Mo,We 9:00 AM&thinsp;&ndash;&thinsp;5:00 PM; Tu,Th 10:00 AM&thinsp;&ndash;&thinsp;5:00 PM', 'business-profile' ), $slots );
373
+ ?>
374
 
375
+ </div>
 
 
376
 
377
+ <?php
378
+ return;
379
+ endif; // Brief opening hours.
380
+
381
+ $weekdays_display = array(
382
+ 'monday' => __( 'Monday' ),
383
+ 'tuesday' => __( 'Tuesday' ),
384
+ 'wednesday' => __( 'Wednesday' ),
385
+ 'thursday' => __( 'Thursday' ),
386
+ 'friday' => __( 'Friday' ),
387
+ 'saturday' => __( 'Saturday' ),
388
+ 'sunday' => __( 'Sunday' ),
389
+ );
390
+
391
+ $weekdays = array();
392
+ foreach ( $hours as $rule ) {
393
+
394
+ // Skip this entry if no weekdays are set.
395
+ if ( empty( $rule['weekdays'] ) ) {
396
  continue;
397
  }
398
 
399
+ if ( empty( $rule['time'] ) ) {
400
+ $time = __( 'Open', 'business-profile' );
 
 
 
 
 
 
 
 
 
 
 
 
401
 
 
 
402
  } else {
403
+
404
+ if ( ! empty( $rule['time']['start'] ) ) {
405
+ $start = new DateTime( $rule['time']['start'] );
 
406
  }
407
+ if ( ! empty( $rule['time']['end'] ) ) {
408
+ $end = new DateTime( $rule['time']['end'] );
409
  }
410
 
411
  if ( empty( $start ) ) {
412
+ $time = __( 'Open until ', 'business-profile' ) . $end->format( get_option( 'time_format' ) );
413
  } elseif ( empty( $end ) ) {
414
+ $time = __( 'Open from ', 'business-profile' ) . $start->format( get_option( 'time_format' ) );
415
  } else {
416
+ $time = $start->format( get_option( 'time_format' ) ) . _x( '&thinsp;&ndash;&thinsp;', 'Separator between opening and closing times. Example: 9:00am&thinsp;&ndash;&thinsp;5:00pm', 'business-profile' ) . $end->format( get_option( 'time_format' ) );
417
  }
418
  }
419
 
420
+ foreach ( $rule['weekdays'] as $day => $val ) {
 
 
 
 
421
 
422
+ if ( ! array_key_exists( $day, $weekdays ) ) {
423
+ $weekdays[ $day ] = array();
424
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
425
 
426
+ $weekdays[ $day ][] = $time;
427
+ }
 
428
  }
429
 
430
+ if ( count( $weekdays ) ) {
 
 
 
431
 
432
+ // Order the weekdays and add any missing days as "closed".
433
+ $weekdays_ordered = array();
434
+ foreach ( $weekdays_display as $slug => $name ) {
435
+ if ( ! array_key_exists( $slug, $weekdays ) ) {
436
+ $weekdays_ordered[ $slug ] = array( __( 'Closed', 'business-profile' ) );
437
+ } else {
438
+ $weekdays_ordered[ $slug ] = $weekdays[ $slug ];
439
+ }
440
  }
441
 
442
+ $data = array(
443
+ 'weekday_hours' => $weekdays_ordered,
444
+ 'weekday_names' => $weekdays_display,
445
+ );
446
+
447
+ $template = new bpfwpTemplateLoader;
448
+ $template->set_template_data( $data );
449
+
450
+ if ( bpfwp_get_display( 'location' ) ) {
451
+ $template->get_template_part( 'opening-hours', bpfwp_get_display( 'location' ) );
452
  } else {
453
+ $template->get_template_part( 'opening-hours' );
454
  }
455
  }
456
+ }
457
+ }
458
 
459
+ if ( ! function_exists( 'bpfwp_print_opening_hours_metatag' ) ) {
460
+ /**
461
+ * Print a schema metatags with the opening hours
462
+ *
463
+ * @access public
464
+ * @param array $hours A list of opening hours.
465
+ * @return void
466
+ */
467
+ function bpfwp_print_opening_hours_metatag( $hours ) {
468
+
469
+ $weekdays_schema = array(
470
+ 'monday' => 'Mo',
471
+ 'tuesday' => 'Tu',
472
+ 'wednesday' => 'We',
473
+ 'thursday' => 'Th',
474
+ 'friday' => 'Fr',
475
+ 'saturday' => 'Sa',
476
+ 'sunday' => 'Su',
477
+ );
478
+
479
+ // Output proper schema.org format.
480
+ foreach ( $hours as $slot ) {
481
+
482
+ // Skip this entry if no weekdays are set.
483
+ if ( empty( $slot['weekdays'] ) ) {
484
+ continue;
485
+ }
486
 
487
+ $days = array();
488
+ foreach ( $slot['weekdays'] as $day => $val ) {
489
+ $days[] = $weekdays_schema[ $day ];
490
  }
491
+ $string = ! empty( $days ) ? join( ',', $days ) : '';
492
 
493
+ if ( ! empty( $string ) && ! empty( $slot['time'] ) ) {
494
+
495
+ if ( empty( $slot['time']['start'] ) ) {
496
+ $start = '00:00';
497
+ } else {
498
+ $start = trim( substr( $slot['time']['start'], 0, -2 ) );
499
+ if ( 'PM' === substr( $slot['time']['start'], -2 ) && '12:00' !== $start ) {
500
+ $split = explode( ':', $start );
501
+ $split[0] += 12;
502
+ $start = join( ':', $split );
503
+ }
504
+ if ( 'AM' === substr( $slot['time']['start'], -2 ) && '12:00' === $start ) {
505
+ $start = '00:00';
506
+ }
507
+ }
508
+
509
+ if ( empty( $slot['time']['end'] ) ) {
510
+ $end = '24:00';
511
+ } else {
512
+ $end = trim( substr( $slot['time']['end'], 0, -2 ) );
513
+ if ( 'PM' === substr( $slot['time']['end'], -2 ) ) {
514
+ $split = explode( ':', $end );
515
+ $split[0] += 12;
516
+ $end = join( ':', $split );
517
+ }
518
+ if ( ! empty( $slot['time']['start'] ) && 'AM' === substr( $slot['time']['start'], -2 ) && '12:00' === $start ) {
519
+ $end = '24:00';
520
+ }
521
+ }
522
+
523
+ $string .= ' ' . $start . '-' . $end;
524
+ }
525
+ echo '<meta itemprop="openingHours" content="' . esc_attr( $string ) . '">';
526
  }
527
  }
528
+ }
529
 
530
+ if ( ! function_exists( 'bpwfwp_print_map' ) ) {
531
+ /**
532
+ * Print a map to the address
533
+ *
534
+ * @since 0.0.1
535
+ * @access public
536
+ * @param string $location The location associated with the map.
537
+ * @return string|void Returns an empty string if no map exists.
538
+ */
539
+ function bpwfwp_print_map( $location = false ) {
540
+
541
+ $address = bpfwp_setting( 'address', $location );
542
+
543
+ if ( empty( $address['text'] ) || ! bpfwp_get_display( 'show_map' ) ) {
544
+ return '';
545
+ }
546
 
547
+ global $bpfwp_controller;
548
+
549
+ if ( ! $bpfwp_controller->get_theme_support( 'disable_scripts' ) ) {
550
+ wp_enqueue_script( 'bpfwp-map' );
551
+ wp_localize_script(
552
+ 'bpfwp-map',
553
+ 'bpfwp_map',
554
+ array(
555
+ // Override loading and intialization of Google Maps api.
556
+ 'autoload_google_maps' => apply_filters( 'bpfwp_autoload_google_maps', true ),
557
+ 'map_options' => apply_filters( 'bpfwp_google_map_options', array() ),
558
+ 'strings' => array(
559
+ 'getDirections' => __( 'Get Directions', 'business-profile' ),
560
+ ),
561
+ )
562
+ );
563
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
564
 
565
+ global $bpfwp_map_ids;
566
+ if ( empty( $bpfwp_map_ids ) ) {
567
+ $bpfwp_map_ids = array();
568
+ }
569
 
570
+ $id = count( $bpfwp_map_ids );
571
+ $bpfwp_map_ids[] = $id;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
572
 
573
+ $attr = '';
 
 
 
574
 
575
+ $phone = bpfwp_setting( 'phone', $location );
576
+ if ( ! empty( $phone ) ) {
577
+ $attr .= ' data-phone="' . esc_attr( $phone ) . '"';
578
+ }
579
 
580
+ if ( ! empty( $address['lat'] ) && ! empty( $address['lon'] ) ) {
581
+ $attr .= ' data-lat="' . esc_attr( $address['lat'] ) . '" data-lon="' . esc_attr( $address['lon'] ) . '"';
582
+ }
583
+ ?>
584
 
585
+ <div id="bp-map-<?php echo $id; ?>" class="bp-map" itemprop="map" data-name="<?php echo esc_attr( bpfwp_setting( 'name', $location ) ); ?>" data-address="<?php echo esc_attr( $address['text'] ); ?>"<?php echo $attr; ?>></div>
586
 
587
+ <?php
 
 
588
  }
589
+ }
590
 
591
+ if ( ! function_exists( 'bpfwp_print_parent_organization' ) ) {
592
+ /**
593
+ * Print a meta tag which connects a location to a `parentOrganization`
594
+ *
595
+ * @since 1.1
596
+ * @access public
597
+ * @return string|void Returns an empty string if no parent location exists.
598
+ */
599
+ function bpfwp_print_parent_organization() {
600
 
601
+ $location = bpfwp_get_display( 'location' );
602
+
603
+ if ( empty( $location ) ) {
604
+ return '';
605
+ }
606
 
607
+ ?>
608
+
609
+ <meta itemprop="parentOrganization" itemtype="http://schema.org/<?php echo esc_attr( bpfwp_setting( 'schema-type' ) ); ?>" content="<?php echo esc_attr( bpfwp_setting( 'name' ) ); ?>">
610
+
611
+ <?php
612
+ }
613
  }
 
languages/business-profile.pot CHANGED
@@ -2,9 +2,9 @@
2
  # This file is distributed under the same license as the Business Profile package.
3
  msgid ""
4
  msgstr ""
5
- "Project-Id-Version: Business Profile 1.0.8\n"
6
- "Report-Msgid-Bugs-To: http://wordpress.org/support/plugin/business-profile\n"
7
- "POT-Creation-Date: 2016-02-12 16:47:11+00:00\n"
8
  "MIME-Version: 1.0\n"
9
  "Content-Type: text/plain; charset=utf-8\n"
10
  "Content-Transfer-Encoding: 8bit\n"
@@ -24,299 +24,377 @@ msgstr ""
24
  "X-Poedit-Bookmarks: \n"
25
  "X-Textdomain-Support: yes\n"
26
 
27
- #: business-profile.php:110
28
  msgid "View the help documentation for Business Profile"
29
  msgstr ""
30
 
31
- #: business-profile.php:110
32
  msgid "Help"
33
  msgstr ""
34
 
35
- #: includes/Integrations.class.php:107
36
- msgid "Book a table"
37
  msgstr ""
38
 
39
- #: includes/Integrations.class.php:127 includes/Integrations.class.php:131
40
- msgid "Show book a table link"
41
  msgstr ""
42
 
43
- #: includes/Settings.class.php:86 includes/Settings.class.php:87
44
- #. #-#-#-#-# business-profile.pot (Business Profile 1.0.8) #-#-#-#-#
45
- #. Plugin Name of the plugin/theme
46
- msgid "Business Profile"
47
  msgstr ""
48
 
49
- #: includes/Settings.class.php:98
50
- msgid "Search Engine Optimization"
51
  msgstr ""
52
 
53
- #: includes/Settings.class.php:108
54
- msgid "Schema Type"
 
 
 
 
 
 
 
 
 
 
 
 
55
  msgstr ""
56
 
57
- #: includes/Settings.class.php:109
 
 
 
 
58
  msgid ""
59
- "Select the option that best describes your business to improve how search "
60
- "engines understand your website"
61
  msgstr ""
62
 
63
- #: includes/Settings.class.php:152
64
- msgid "Contact Information"
65
  msgstr ""
66
 
67
- #: includes/Settings.class.php:162
68
- msgid "Name"
 
69
  msgstr ""
70
 
71
- #: includes/Settings.class.php:163
72
- msgid "Enter the name of your business if it is different than the website name."
73
  msgstr ""
74
 
75
- #: includes/Settings.class.php:174
76
- msgid "Address"
 
 
 
77
  msgstr ""
78
 
79
- #: includes/Settings.class.php:178
80
- msgid "No map coordinates set."
81
  msgstr ""
82
 
83
- #: includes/Settings.class.php:179
84
- msgid "Requesting new coordinates"
85
  msgstr ""
86
 
87
- #: includes/Settings.class.php:180
88
- msgid "Select a match below"
89
  msgstr ""
90
 
91
- #: includes/Settings.class.php:181
92
- msgid "View"
93
  msgstr ""
94
 
95
- #: includes/Settings.class.php:182
96
- msgid "Retrieve map coordinates"
97
  msgstr ""
98
 
99
- #: includes/Settings.class.php:183
100
- msgid "Remove map coordinates"
101
  msgstr ""
102
 
103
- #: includes/Settings.class.php:184
104
- msgid "Try again?"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
105
  msgstr ""
106
 
107
- #: includes/Settings.class.php:185
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
108
  msgid "Error"
109
  msgstr ""
110
 
111
- #: includes/Settings.class.php:186
112
  msgid ""
113
  "Invalid request. Be sure to fill out the address field before retrieving "
114
  "coordinates."
115
  msgstr ""
116
 
117
- #: includes/Settings.class.php:187
118
  msgid "Request denied."
119
  msgstr ""
120
 
121
- #: includes/Settings.class.php:188
122
  msgid "Request denied because you are over your request quota."
123
  msgstr ""
124
 
125
- #: includes/Settings.class.php:189
126
- msgid "Nothing was found at that address"
127
  msgstr ""
128
 
129
- #: includes/Settings.class.php:200
130
- msgid "Phone"
131
  msgstr ""
132
 
133
- #: includes/Settings.class.php:210
134
- msgid "Contact Page"
135
  msgstr ""
136
 
137
- #: includes/Settings.class.php:211
138
- msgid ""
139
- "Select a page on your site where users can reach you, such as a contact "
140
- "form."
141
  msgstr ""
142
 
143
- #: includes/Settings.class.php:227
144
  msgid "Email Address (optional)"
145
  msgstr ""
146
 
147
- #: includes/Settings.class.php:228
148
- msgid ""
149
- "Enter an email address only if you want to display this publicly. Showing "
150
- "your email address on your site may cause you to receive excessive spam."
151
- msgstr ""
152
-
153
- #: includes/Settings.class.php:236
154
- msgid "Schedule"
155
  msgstr ""
156
 
157
- #: includes/Settings.class.php:246 includes/template-functions.php:398
158
- msgid "Opening Hours"
159
- msgstr ""
160
-
161
- #: includes/Settings.class.php:247
162
  msgid "Define your weekly opening hours by adding scheduling rules."
163
  msgstr ""
164
 
165
- #: includes/Settings.class.php:262
166
  msgid "Add another opening time"
167
  msgstr ""
168
 
169
- #: includes/Settings.class.php:276
170
  msgid "Delete scheduling rule"
171
  msgstr ""
172
 
173
- #: includes/Settings.class.php:293
174
- msgid "Display"
 
 
 
175
  msgstr ""
176
 
177
- #: includes/Settings.class.php:303
178
- msgid "Shortcode"
179
  msgstr ""
180
 
181
- #: includes/Settings.class.php:305
182
  msgid ""
183
- "Paste this shortcode into any page or post to display your contact details. "
184
- "Learn about %sall of the attributes%s in the documentation."
185
  msgstr ""
186
 
187
- #: includes/WP_Widget.ContactCardWidget.class.php:25
188
- msgid "Show Name"
189
  msgstr ""
190
 
191
- #: includes/WP_Widget.ContactCardWidget.class.php:26
192
- msgid "Show Address"
193
  msgstr ""
194
 
195
- #: includes/WP_Widget.ContactCardWidget.class.php:27
196
- msgid "Show link to get directions on Google Maps"
197
  msgstr ""
198
 
199
- #: includes/WP_Widget.ContactCardWidget.class.php:28
200
- msgid "Show Phone number"
201
  msgstr ""
202
 
203
- #: includes/WP_Widget.ContactCardWidget.class.php:29
204
- msgid "Show contact details"
205
  msgstr ""
206
 
207
- #: includes/WP_Widget.ContactCardWidget.class.php:30
208
- msgid "Show Opening Hours"
209
  msgstr ""
210
 
211
- #: includes/WP_Widget.ContactCardWidget.class.php:31
212
- msgid "Show brief opening hours on one line"
213
  msgstr ""
214
 
215
- #: includes/WP_Widget.ContactCardWidget.class.php:32
216
- msgid "Show Google Map"
 
 
217
  msgstr ""
218
 
219
- #: includes/WP_Widget.ContactCardWidget.class.php:38
220
- msgid "Contact Card"
 
 
221
  msgstr ""
222
 
223
- #: includes/WP_Widget.ContactCardWidget.class.php:39
224
- msgid ""
225
- "Display a contact card with your name, address, phone number, opening hours "
226
- "and map."
227
  msgstr ""
228
 
229
- #: includes/WP_Widget.ContactCardWidget.class.php:85
230
- msgid "Title"
 
 
 
 
231
  msgstr ""
232
 
233
- #: includes/template-functions.php:132 includes/template-functions.php:436
 
 
 
 
 
 
 
 
 
234
  msgid "Get directions"
235
  msgstr ""
236
 
237
- #: includes/template-functions.php:190
238
  msgid "Contact"
239
  msgstr ""
240
 
241
- #: includes/template-functions.php:289
242
  msgid "Mo"
243
  msgstr ""
244
 
245
- #: includes/template-functions.php:290
246
  msgid "Tu"
247
  msgstr ""
248
 
249
- #: includes/template-functions.php:291
250
  msgid "We"
251
  msgstr ""
252
 
253
- #: includes/template-functions.php:292
254
  msgid "Th"
255
  msgstr ""
256
 
257
- #: includes/template-functions.php:293
258
  msgid "Fr"
259
  msgstr ""
260
 
261
- #: includes/template-functions.php:294
262
  msgid "Sa"
263
  msgstr ""
264
 
265
- #: includes/template-functions.php:295
266
  msgid "Su"
267
  msgstr ""
268
 
269
- #: includes/template-functions.php:336
270
  msgid "Monday"
271
  msgstr ""
272
 
273
- #: includes/template-functions.php:337
274
  msgid "Tuesday"
275
  msgstr ""
276
 
277
- #: includes/template-functions.php:338
278
  msgid "Wednesday"
279
  msgstr ""
280
 
281
- #: includes/template-functions.php:339
282
  msgid "Thursday"
283
  msgstr ""
284
 
285
- #: includes/template-functions.php:340
286
  msgid "Friday"
287
  msgstr ""
288
 
289
- #: includes/template-functions.php:341
290
  msgid "Saturday"
291
  msgstr ""
292
 
293
- #: includes/template-functions.php:342
294
  msgid "Sunday"
295
  msgstr ""
296
 
297
- #: includes/template-functions.php:354
298
  msgid "Open"
299
  msgstr ""
300
 
301
- #: includes/template-functions.php:366
302
  msgid "Open until "
303
  msgstr ""
304
 
305
- #: includes/template-functions.php:368
306
  msgid "Open from "
307
  msgstr ""
308
 
309
- #: includes/template-functions.php:390
310
  msgid "Closed"
311
  msgstr ""
312
 
 
 
 
 
313
  #: lib/simple-admin-pages/classes/AdminPage.class.php:173
314
  msgid "You do not have sufficient permissions to access this page."
315
  msgstr ""
316
 
317
- #. #-#-#-#-# business-profile.pot (Business Profile 1.0.8) #-#-#-#-#
318
  #. Plugin URI of the plugin/theme
319
- #. #-#-#-#-# business-profile.pot (Business Profile 1.0.8) #-#-#-#-#
320
  #. Author URI of the plugin/theme
321
  msgid "http://themeofthecrop.com"
322
  msgstr ""
@@ -329,52 +407,53 @@ msgstr ""
329
  msgid "Theme of the Crop"
330
  msgstr ""
331
 
332
- #: includes/Settings.class.php:176
333
- msgctxt "separator between admin action links in address component"
334
- msgid " | "
335
- msgstr ""
336
-
337
- #: includes/Settings.class.php:177
338
  msgctxt "separates latitude and longitude"
339
  msgid ", "
340
  msgstr ""
341
 
342
- #: includes/Settings.class.php:249
 
 
 
 
 
343
  msgctxt "Monday abbreviation"
344
  msgid "Mo"
345
  msgstr ""
346
 
347
- #: includes/Settings.class.php:250
348
  msgctxt "Tuesday abbreviation"
349
  msgid "Tu"
350
  msgstr ""
351
 
352
- #: includes/Settings.class.php:251
353
  msgctxt "Wednesday abbreviation"
354
  msgid "We"
355
  msgstr ""
356
 
357
- #: includes/Settings.class.php:252
358
  msgctxt "Thursday abbreviation"
359
  msgid "Th"
360
  msgstr ""
361
 
362
- #: includes/Settings.class.php:253
363
  msgctxt "Friday abbreviation"
364
  msgid "Fr"
365
  msgstr ""
366
 
367
- #: includes/Settings.class.php:254
368
  msgctxt "Saturday abbreviation"
369
  msgid "Sa"
370
  msgstr ""
371
 
372
- #: includes/Settings.class.php:255
373
  msgctxt "Sunday abbreviation"
374
  msgid "Su"
375
  msgstr ""
376
 
377
- #: includes/Settings.class.php:257
378
  msgctxt ""
379
  "Time format displayed in the opening hours setting panel in your admin "
380
  "area. Must match formatting rules at "
@@ -382,7 +461,7 @@ msgctxt ""
382
  msgid "h:i A"
383
  msgstr ""
384
 
385
- #: includes/Settings.class.php:258
386
  msgctxt ""
387
  "Date format displayed in the opening hours setting panel in your admin "
388
  "area. Must match formatting rules at "
@@ -390,86 +469,86 @@ msgctxt ""
390
  msgid "mmmm d, yyyy"
391
  msgstr ""
392
 
393
- #: includes/Settings.class.php:263
394
  msgctxt "Format of a scheduling rule"
395
  msgid "Weekly"
396
  msgstr ""
397
 
398
- #: includes/Settings.class.php:264
399
  msgctxt "Format of a scheduling rule"
400
  msgid "Monthly"
401
  msgstr ""
402
 
403
- #: includes/Settings.class.php:265
404
  msgctxt "Format of a scheduling rule"
405
  msgid "Date"
406
  msgstr ""
407
 
408
- #: includes/Settings.class.php:266
409
  msgctxt "Label for selecting days of the week in a scheduling rule"
410
  msgid "Days of the week"
411
  msgstr ""
412
 
413
- #: includes/Settings.class.php:267
414
  msgctxt "Label for selecting weeks of the month in a scheduling rule"
415
  msgid "Weeks of the month"
416
  msgstr ""
417
 
418
- #: includes/Settings.class.php:268
419
  msgctxt "Label to select a date for a scheduling rule"
420
  msgid "Date"
421
  msgstr ""
422
 
423
- #: includes/Settings.class.php:269
424
  msgctxt "Label to select a time slot for a scheduling rule"
425
  msgid "Time"
426
  msgstr ""
427
 
428
- #: includes/Settings.class.php:270
429
  msgctxt "Label to set a scheduling rule to last all day"
430
  msgid "All day"
431
  msgstr ""
432
 
433
- #: includes/Settings.class.php:271
434
  msgctxt "Label for the starting time of a scheduling rule"
435
  msgid "Start"
436
  msgstr ""
437
 
438
- #: includes/Settings.class.php:272
439
  msgctxt "Label for the ending time of a scheduling rule"
440
  msgid "End"
441
  msgstr ""
442
 
443
- #: includes/Settings.class.php:273
444
  msgctxt "Prompt displayed when a scheduling rule is set without any time restrictions"
445
  msgid "All day long. Want to %sset a time slot%s?"
446
  msgstr ""
447
 
448
- #: includes/Settings.class.php:274
449
  msgctxt "Toggle a scheduling rule open and closed"
450
  msgid "Open and close this rule"
451
  msgstr ""
452
 
453
- #: includes/Settings.class.php:275
454
  msgctxt "Delete a scheduling rule"
455
  msgid "Delete rule"
456
  msgstr ""
457
 
458
- #: includes/Settings.class.php:277
459
  msgctxt ""
460
  "Brief default description of a scheduling rule when no weekdays or weeks "
461
  "are included in the rule"
462
  msgid "Never"
463
  msgstr ""
464
 
465
- #: includes/Settings.class.php:278
466
  msgctxt ""
467
  "Brief default description of a scheduling rule when all the weekdays/weeks "
468
  "are included in the rule"
469
  msgid "Every day"
470
  msgstr ""
471
 
472
- #: includes/Settings.class.php:279
473
  msgctxt ""
474
  "Brief default description of a scheduling rule when some weekdays are "
475
  "included on only some weeks of the month. %s should be left alone and will "
@@ -478,7 +557,7 @@ msgctxt ""
478
  msgid "%s on the %s week of the month"
479
  msgstr ""
480
 
481
- #: includes/Settings.class.php:280
482
  msgctxt ""
483
  "Brief default description of a scheduling rule when some weeks of the month "
484
  "are included but all or no weekdays are selected. %s should be left alone "
@@ -487,73 +566,77 @@ msgctxt ""
487
  msgid "%s week of the month"
488
  msgstr ""
489
 
490
- #: includes/Settings.class.php:281
491
  msgctxt "Brief default description of a scheduling rule when no times are set"
492
  msgid "All day"
493
  msgstr ""
494
 
495
- #: includes/Settings.class.php:282
496
  msgctxt ""
497
  "Brief default description of a scheduling rule when an end time is set but "
498
  "no start time. If the end time is 6pm, it will read: Ends at 6pm"
499
  msgid "Ends at"
500
  msgstr ""
501
 
502
- #: includes/Settings.class.php:283
503
  msgctxt ""
504
  "Brief default description of a scheduling rule when a start time is set but "
505
  "no end time. If the start time is 6pm, it will read: Starts at 6pm"
506
  msgid "Starts at"
507
  msgstr ""
508
 
509
- #: includes/Settings.class.php:284
510
  msgctxt "Separator between times of a scheduling rule"
511
  msgid "&mdash;"
512
  msgstr ""
513
 
514
- #: includes/template-functions.php:300
515
  msgctxt ""
516
  "Separator between days of the week when displaying opening hours in brief. "
517
  "Example: Mo,Tu,We"
518
  msgid ","
519
  msgstr ""
520
 
521
- #: includes/template-functions.php:303
522
  msgctxt ""
523
  "Brief opening hours description which lists days_strings when open all day. "
524
  "Example: Mo,Tu,We all day"
525
  msgid "%s all day"
526
  msgstr ""
527
 
528
- #: includes/template-functions.php:315
529
  msgctxt ""
530
  "Brief opening hours description which lists the days followed by the "
531
  "closing time. Example: Mo,Tu,We open until 9:00pm"
532
  msgid "%s open until %s"
533
  msgstr ""
534
 
535
- #: includes/template-functions.php:317
536
  msgctxt ""
537
  "Brief opening hours description which lists the days followed by the "
538
  "opening time. Example: Mo,Tu,We open from 9:00am"
539
  msgid "%s open from %s"
540
  msgstr ""
541
 
542
- #: includes/template-functions.php:319
543
  msgctxt ""
544
  "Brief opening hours description which lists the days followed by the "
545
- "opening and closing times. Example: Mo,Tu,We 9:00am-5:00pm"
546
- msgid "%s %s-%s"
 
547
  msgstr ""
548
 
549
- #: includes/template-functions.php:326
550
  msgctxt ""
551
  "Separator between multiple opening times in the brief opening hours. "
552
- "Example: Mo,We 9:00 AM - 5:00 PM; Tu,Th 10:00 AM - 5:00 PM"
 
553
  msgid "; "
554
  msgstr ""
555
 
556
- #: includes/template-functions.php:370
557
- msgctxt "Separator between opening and closing times. Example: 9:00am-5:00pm"
558
- msgid "-"
 
 
559
  msgstr ""
2
  # This file is distributed under the same license as the Business Profile package.
3
  msgid ""
4
  msgstr ""
5
+ "Project-Id-Version: Business Profile 1.1\n"
6
+ "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/business-profile\n"
7
+ "POT-Creation-Date: 2016-06-20 06:53:53+00:00\n"
8
  "MIME-Version: 1.0\n"
9
  "Content-Type: text/plain; charset=utf-8\n"
10
  "Content-Transfer-Encoding: 8bit\n"
24
  "X-Poedit-Bookmarks: \n"
25
  "X-Textdomain-Support: yes\n"
26
 
27
+ #: business-profile.php:226
28
  msgid "View the help documentation for Business Profile"
29
  msgstr ""
30
 
31
+ #: business-profile.php:227
32
  msgid "Help"
33
  msgstr ""
34
 
35
+ #: includes/class-contact-card-widget.php:39
36
+ msgid "Show Name"
37
  msgstr ""
38
 
39
+ #: includes/class-contact-card-widget.php:40
40
+ msgid "Show Address"
41
  msgstr ""
42
 
43
+ #: includes/class-contact-card-widget.php:41
44
+ msgid "Show link to get directions on Google Maps"
 
 
45
  msgstr ""
46
 
47
+ #: includes/class-contact-card-widget.php:42
48
+ msgid "Show Phone number"
49
  msgstr ""
50
 
51
+ #: includes/class-contact-card-widget.php:43
52
+ msgid "Show contact details"
53
+ msgstr ""
54
+
55
+ #: includes/class-contact-card-widget.php:44
56
+ msgid "Show Opening Hours"
57
+ msgstr ""
58
+
59
+ #: includes/class-contact-card-widget.php:45
60
+ msgid "Show brief opening hours on one line"
61
+ msgstr ""
62
+
63
+ #: includes/class-contact-card-widget.php:46
64
+ msgid "Show Google Map"
65
  msgstr ""
66
 
67
+ #: includes/class-contact-card-widget.php:52
68
+ msgid "Contact Card"
69
+ msgstr ""
70
+
71
+ #: includes/class-contact-card-widget.php:53
72
  msgid ""
73
+ "Display a contact card with your name, address, phone number, opening hours "
74
+ "and map."
75
  msgstr ""
76
 
77
+ #: includes/class-contact-card-widget.php:91
78
+ msgid "Title"
79
  msgstr ""
80
 
81
+ #: includes/class-contact-card-widget.php:117
82
+ #: includes/class-custom-post-types.php:60
83
+ msgid "Location"
84
  msgstr ""
85
 
86
+ #: includes/class-contact-card-widget.php:119
87
+ msgid "Use Primary Business Profile"
88
  msgstr ""
89
 
90
+ #: includes/class-custom-post-types.php:59
91
+ #: includes/class-custom-post-types.php:61
92
+ #: includes/class-custom-post-types.php:62 includes/class-settings.php:208
93
+ #: includes/class-settings.php:209
94
+ msgid "Locations"
95
  msgstr ""
96
 
97
+ #: includes/class-custom-post-types.php:63
98
+ msgid "Add New"
99
  msgstr ""
100
 
101
+ #: includes/class-custom-post-types.php:64
102
+ msgid "Add New Location"
103
  msgstr ""
104
 
105
+ #: includes/class-custom-post-types.php:65
106
+ msgid "Edit Location"
107
  msgstr ""
108
 
109
+ #: includes/class-custom-post-types.php:66
110
+ msgid "New Location"
111
  msgstr ""
112
 
113
+ #: includes/class-custom-post-types.php:67
114
+ msgid "View Location"
115
  msgstr ""
116
 
117
+ #: includes/class-custom-post-types.php:68
118
+ msgid "Search Locations"
119
  msgstr ""
120
 
121
+ #: includes/class-custom-post-types.php:69
122
+ msgid "No locations found"
123
+ msgstr ""
124
+
125
+ #: includes/class-custom-post-types.php:70
126
+ msgid "No locations found in trash"
127
+ msgstr ""
128
+
129
+ #: includes/class-custom-post-types.php:71
130
+ msgid "All Locations"
131
+ msgstr ""
132
+
133
+ #: includes/class-custom-post-types.php:146 includes/class-settings.php:257
134
+ msgid "Schema Type"
135
+ msgstr ""
136
+
137
+ #: includes/class-custom-post-types.php:157
138
+ msgid "Contact Details"
139
+ msgstr ""
140
+
141
+ #: includes/class-custom-post-types.php:167
142
+ #: includes/class-custom-post-types.php:407 includes/class-settings.php:362
143
+ #: templates/opening-hours.php:21
144
+ msgid "Opening Hours"
145
+ msgstr ""
146
+
147
+ #: includes/class-custom-post-types.php:228
148
+ msgid "Schema type"
149
+ msgstr ""
150
+
151
+ #: includes/class-custom-post-types.php:238
152
+ msgid ""
153
+ "Select the option that best describes your business to improve how search "
154
+ "engines understand your website."
155
  msgstr ""
156
 
157
+ #: includes/class-custom-post-types.php:264
158
+ #: includes/class-custom-post-types.php:288 includes/class-settings.php:294
159
+ msgid "No map coordinates set."
160
+ msgstr ""
161
+
162
+ #: includes/class-custom-post-types.php:266 includes/class-settings.php:295
163
+ msgid "Requesting new coordinates"
164
+ msgstr ""
165
+
166
+ #: includes/class-custom-post-types.php:267 includes/class-settings.php:296
167
+ msgid "Select a match below"
168
+ msgstr ""
169
+
170
+ #: includes/class-custom-post-types.php:268
171
+ #: includes/class-custom-post-types.php:291 includes/class-settings.php:297
172
+ msgid "View"
173
+ msgstr ""
174
+
175
+ #: includes/class-custom-post-types.php:269 includes/class-settings.php:301
176
  msgid "Error"
177
  msgstr ""
178
 
179
+ #: includes/class-custom-post-types.php:270 includes/class-settings.php:302
180
  msgid ""
181
  "Invalid request. Be sure to fill out the address field before retrieving "
182
  "coordinates."
183
  msgstr ""
184
 
185
+ #: includes/class-custom-post-types.php:271 includes/class-settings.php:303
186
  msgid "Request denied."
187
  msgstr ""
188
 
189
+ #: includes/class-custom-post-types.php:272 includes/class-settings.php:304
190
  msgid "Request denied because you are over your request quota."
191
  msgstr ""
192
 
193
+ #: includes/class-custom-post-types.php:273
194
+ msgid "Nothing was found at that address."
195
  msgstr ""
196
 
197
+ #: includes/class-custom-post-types.php:298 includes/class-settings.php:298
198
+ msgid "Retrieve map coordinates"
199
  msgstr ""
200
 
201
+ #: includes/class-custom-post-types.php:302 includes/class-settings.php:299
202
+ msgid "Remove map coordinates"
203
  msgstr ""
204
 
205
+ #: includes/class-custom-post-types.php:330 includes/class-settings.php:326
206
+ msgid "Contact Page"
 
 
207
  msgstr ""
208
 
209
+ #: includes/class-custom-post-types.php:344 includes/class-settings.php:343
210
  msgid "Email Address (optional)"
211
  msgstr ""
212
 
213
+ #: includes/class-custom-post-types.php:351
214
+ msgid "Phone Number"
 
 
 
 
 
 
215
  msgstr ""
216
 
217
+ #: includes/class-custom-post-types.php:408 includes/class-settings.php:363
 
 
 
 
218
  msgid "Define your weekly opening hours by adding scheduling rules."
219
  msgstr ""
220
 
221
+ #: includes/class-custom-post-types.php:423 includes/class-settings.php:378
222
  msgid "Add another opening time"
223
  msgstr ""
224
 
225
+ #: includes/class-custom-post-types.php:437 includes/class-settings.php:392
226
  msgid "Delete scheduling rule"
227
  msgstr ""
228
 
229
+ #: includes/class-settings.php:221 includes/class-settings.php:222
230
+ #: includes/class-settings.php:233 includes/class-settings.php:234
231
+ #. #-#-#-#-# business-profile.pot (Business Profile 1.1) #-#-#-#-#
232
+ #. Plugin Name of the plugin/theme
233
+ msgid "Business Profile"
234
  msgstr ""
235
 
236
+ #: includes/class-settings.php:247
237
+ msgid "Search Engine Optimization"
238
  msgstr ""
239
 
240
+ #: includes/class-settings.php:258
241
  msgid ""
242
+ "Select the option that best describes your business to improve how search "
243
+ "engines understand your website"
244
  msgstr ""
245
 
246
+ #: includes/class-settings.php:268
247
+ msgid "Contact Information"
248
  msgstr ""
249
 
250
+ #: includes/class-settings.php:278
251
+ msgid "Name"
252
  msgstr ""
253
 
254
+ #: includes/class-settings.php:279
255
+ msgid "Enter the name of your business if it is different than the website name."
256
  msgstr ""
257
 
258
+ #: includes/class-settings.php:290
259
+ msgid "Address"
260
  msgstr ""
261
 
262
+ #: includes/class-settings.php:300
263
+ msgid "Try again?"
264
  msgstr ""
265
 
266
+ #: includes/class-settings.php:305
267
+ msgid "Nothing was found at that address"
268
  msgstr ""
269
 
270
+ #: includes/class-settings.php:316
271
+ msgid "Phone"
272
  msgstr ""
273
 
274
+ #: includes/class-settings.php:327
275
+ msgid ""
276
+ "Select a page on your site where users can reach you, such as a contact "
277
+ "form."
278
  msgstr ""
279
 
280
+ #: includes/class-settings.php:344
281
+ msgid ""
282
+ "Enter an email address only if you want to display this publicly. Showing "
283
+ "your email address on your site may cause you to receive excessive spam."
284
  msgstr ""
285
 
286
+ #: includes/class-settings.php:352
287
+ msgid "Schedule"
 
 
288
  msgstr ""
289
 
290
+ #: includes/class-settings.php:409 includes/class-settings.php:419
291
+ msgid "Multiple Locations"
292
+ msgstr ""
293
+
294
+ #: includes/class-settings.php:420
295
+ msgid "Enable support for multiple business locations."
296
  msgstr ""
297
 
298
+ #: includes/deprecated/class-integrations.php:147
299
+ msgid "Book a table"
300
+ msgstr ""
301
+
302
+ #: includes/deprecated/class-integrations.php:170
303
+ #: includes/deprecated/class-integrations.php:173
304
+ msgid "Show book a table link"
305
+ msgstr ""
306
+
307
+ #: includes/template-functions.php:212
308
  msgid "Get directions"
309
  msgstr ""
310
 
311
+ #: includes/template-functions.php:287
312
  msgid "Contact"
313
  msgstr ""
314
 
315
+ #: includes/template-functions.php:335
316
  msgid "Mo"
317
  msgstr ""
318
 
319
+ #: includes/template-functions.php:336
320
  msgid "Tu"
321
  msgstr ""
322
 
323
+ #: includes/template-functions.php:337
324
  msgid "We"
325
  msgstr ""
326
 
327
+ #: includes/template-functions.php:338
328
  msgid "Th"
329
  msgstr ""
330
 
331
+ #: includes/template-functions.php:339
332
  msgid "Fr"
333
  msgstr ""
334
 
335
+ #: includes/template-functions.php:340
336
  msgid "Sa"
337
  msgstr ""
338
 
339
+ #: includes/template-functions.php:341
340
  msgid "Su"
341
  msgstr ""
342
 
343
+ #: includes/template-functions.php:382
344
  msgid "Monday"
345
  msgstr ""
346
 
347
+ #: includes/template-functions.php:383
348
  msgid "Tuesday"
349
  msgstr ""
350
 
351
+ #: includes/template-functions.php:384
352
  msgid "Wednesday"
353
  msgstr ""
354
 
355
+ #: includes/template-functions.php:385
356
  msgid "Thursday"
357
  msgstr ""
358
 
359
+ #: includes/template-functions.php:386
360
  msgid "Friday"
361
  msgstr ""
362
 
363
+ #: includes/template-functions.php:387
364
  msgid "Saturday"
365
  msgstr ""
366
 
367
+ #: includes/template-functions.php:388
368
  msgid "Sunday"
369
  msgstr ""
370
 
371
+ #: includes/template-functions.php:400
372
  msgid "Open"
373
  msgstr ""
374
 
375
+ #: includes/template-functions.php:412
376
  msgid "Open until "
377
  msgstr ""
378
 
379
+ #: includes/template-functions.php:414
380
  msgid "Open from "
381
  msgstr ""
382
 
383
+ #: includes/template-functions.php:436
384
  msgid "Closed"
385
  msgstr ""
386
 
387
+ #: includes/template-functions.php:559
388
+ msgid "Get Directions"
389
+ msgstr ""
390
+
391
  #: lib/simple-admin-pages/classes/AdminPage.class.php:173
392
  msgid "You do not have sufficient permissions to access this page."
393
  msgstr ""
394
 
395
+ #. #-#-#-#-# business-profile.pot (Business Profile 1.1) #-#-#-#-#
396
  #. Plugin URI of the plugin/theme
397
+ #. #-#-#-#-# business-profile.pot (Business Profile 1.1) #-#-#-#-#
398
  #. Author URI of the plugin/theme
399
  msgid "http://themeofthecrop.com"
400
  msgstr ""
407
  msgid "Theme of the Crop"
408
  msgstr ""
409
 
410
+ #: includes/class-custom-post-types.php:265
411
+ #: includes/class-custom-post-types.php:290 includes/class-settings.php:293
 
 
 
 
412
  msgctxt "separates latitude and longitude"
413
  msgid ", "
414
  msgstr ""
415
 
416
+ #: includes/class-custom-post-types.php:300 includes/class-settings.php:292
417
+ msgctxt "separator between admin action links in address component"
418
+ msgid " | "
419
+ msgstr ""
420
+
421
+ #: includes/class-custom-post-types.php:410 includes/class-settings.php:365
422
  msgctxt "Monday abbreviation"
423
  msgid "Mo"
424
  msgstr ""
425
 
426
+ #: includes/class-custom-post-types.php:411 includes/class-settings.php:366
427
  msgctxt "Tuesday abbreviation"
428
  msgid "Tu"
429
  msgstr ""
430
 
431
+ #: includes/class-custom-post-types.php:412 includes/class-settings.php:367
432
  msgctxt "Wednesday abbreviation"
433
  msgid "We"
434
  msgstr ""
435
 
436
+ #: includes/class-custom-post-types.php:413 includes/class-settings.php:368
437
  msgctxt "Thursday abbreviation"
438
  msgid "Th"
439
  msgstr ""
440
 
441
+ #: includes/class-custom-post-types.php:414 includes/class-settings.php:369
442
  msgctxt "Friday abbreviation"
443
  msgid "Fr"
444
  msgstr ""
445
 
446
+ #: includes/class-custom-post-types.php:415 includes/class-settings.php:370
447
  msgctxt "Saturday abbreviation"
448
  msgid "Sa"
449
  msgstr ""
450
 
451
+ #: includes/class-custom-post-types.php:416 includes/class-settings.php:371
452
  msgctxt "Sunday abbreviation"
453
  msgid "Su"
454
  msgstr ""
455
 
456
+ #: includes/class-custom-post-types.php:418 includes/class-settings.php:373
457
  msgctxt ""
458
  "Time format displayed in the opening hours setting panel in your admin "
459
  "area. Must match formatting rules at "
461
  msgid "h:i A"
462
  msgstr ""
463
 
464
+ #: includes/class-custom-post-types.php:419 includes/class-settings.php:374
465
  msgctxt ""
466
  "Date format displayed in the opening hours setting panel in your admin "
467
  "area. Must match formatting rules at "
469
  msgid "mmmm d, yyyy"
470
  msgstr ""
471
 
472
+ #: includes/class-custom-post-types.php:424 includes/class-settings.php:379
473
  msgctxt "Format of a scheduling rule"
474
  msgid "Weekly"
475
  msgstr ""
476
 
477
+ #: includes/class-custom-post-types.php:425 includes/class-settings.php:380
478
  msgctxt "Format of a scheduling rule"
479
  msgid "Monthly"
480
  msgstr ""
481
 
482
+ #: includes/class-custom-post-types.php:426 includes/class-settings.php:381
483
  msgctxt "Format of a scheduling rule"
484
  msgid "Date"
485
  msgstr ""
486
 
487
+ #: includes/class-custom-post-types.php:427 includes/class-settings.php:382
488
  msgctxt "Label for selecting days of the week in a scheduling rule"
489
  msgid "Days of the week"
490
  msgstr ""
491
 
492
+ #: includes/class-custom-post-types.php:428 includes/class-settings.php:383
493
  msgctxt "Label for selecting weeks of the month in a scheduling rule"
494
  msgid "Weeks of the month"
495
  msgstr ""
496
 
497
+ #: includes/class-custom-post-types.php:429 includes/class-settings.php:384
498
  msgctxt "Label to select a date for a scheduling rule"
499
  msgid "Date"
500
  msgstr ""
501
 
502
+ #: includes/class-custom-post-types.php:430 includes/class-settings.php:385
503
  msgctxt "Label to select a time slot for a scheduling rule"
504
  msgid "Time"
505
  msgstr ""
506
 
507
+ #: includes/class-custom-post-types.php:431 includes/class-settings.php:386
508
  msgctxt "Label to set a scheduling rule to last all day"
509
  msgid "All day"
510
  msgstr ""
511
 
512
+ #: includes/class-custom-post-types.php:432 includes/class-settings.php:387
513
  msgctxt "Label for the starting time of a scheduling rule"
514
  msgid "Start"
515
  msgstr ""
516
 
517
+ #: includes/class-custom-post-types.php:433 includes/class-settings.php:388
518
  msgctxt "Label for the ending time of a scheduling rule"
519
  msgid "End"
520
  msgstr ""
521
 
522
+ #: includes/class-custom-post-types.php:434 includes/class-settings.php:389
523
  msgctxt "Prompt displayed when a scheduling rule is set without any time restrictions"
524
  msgid "All day long. Want to %sset a time slot%s?"
525
  msgstr ""
526
 
527
+ #: includes/class-custom-post-types.php:435 includes/class-settings.php:390
528
  msgctxt "Toggle a scheduling rule open and closed"
529
  msgid "Open and close this rule"
530
  msgstr ""
531
 
532
+ #: includes/class-custom-post-types.php:436 includes/class-settings.php:391
533
  msgctxt "Delete a scheduling rule"
534
  msgid "Delete rule"
535
  msgstr ""
536
 
537
+ #: includes/class-custom-post-types.php:438 includes/class-settings.php:393
538
  msgctxt ""
539
  "Brief default description of a scheduling rule when no weekdays or weeks "
540
  "are included in the rule"
541
  msgid "Never"
542
  msgstr ""
543
 
544
+ #: includes/class-custom-post-types.php:439 includes/class-settings.php:394
545
  msgctxt ""
546
  "Brief default description of a scheduling rule when all the weekdays/weeks "
547
  "are included in the rule"
548
  msgid "Every day"
549
  msgstr ""
550
 
551
+ #: includes/class-custom-post-types.php:440 includes/class-settings.php:395
552
  msgctxt ""
553
  "Brief default description of a scheduling rule when some weekdays are "
554
  "included on only some weeks of the month. %s should be left alone and will "
557
  msgid "%s on the %s week of the month"
558
  msgstr ""
559
 
560
+ #: includes/class-custom-post-types.php:441 includes/class-settings.php:396
561
  msgctxt ""
562
  "Brief default description of a scheduling rule when some weeks of the month "
563
  "are included but all or no weekdays are selected. %s should be left alone "
566
  msgid "%s week of the month"
567
  msgstr ""
568
 
569
+ #: includes/class-custom-post-types.php:442 includes/class-settings.php:397
570
  msgctxt "Brief default description of a scheduling rule when no times are set"
571
  msgid "All day"
572
  msgstr ""
573
 
574
+ #: includes/class-custom-post-types.php:443 includes/class-settings.php:398
575
  msgctxt ""
576
  "Brief default description of a scheduling rule when an end time is set but "
577
  "no start time. If the end time is 6pm, it will read: Ends at 6pm"
578
  msgid "Ends at"
579
  msgstr ""
580
 
581
+ #: includes/class-custom-post-types.php:444 includes/class-settings.php:399
582
  msgctxt ""
583
  "Brief default description of a scheduling rule when a start time is set but "
584
  "no end time. If the start time is 6pm, it will read: Starts at 6pm"
585
  msgid "Starts at"
586
  msgstr ""
587
 
588
+ #: includes/class-custom-post-types.php:445 includes/class-settings.php:400
589
  msgctxt "Separator between times of a scheduling rule"
590
  msgid "&mdash;"
591
  msgstr ""
592
 
593
+ #: includes/template-functions.php:346
594
  msgctxt ""
595
  "Separator between days of the week when displaying opening hours in brief. "
596
  "Example: Mo,Tu,We"
597
  msgid ","
598
  msgstr ""
599
 
600
+ #: includes/template-functions.php:349
601
  msgctxt ""
602
  "Brief opening hours description which lists days_strings when open all day. "
603
  "Example: Mo,Tu,We all day"
604
  msgid "%s all day"
605
  msgstr ""
606
 
607
+ #: includes/template-functions.php:361
608
  msgctxt ""
609
  "Brief opening hours description which lists the days followed by the "
610
  "closing time. Example: Mo,Tu,We open until 9:00pm"
611
  msgid "%s open until %s"
612
  msgstr ""
613
 
614
+ #: includes/template-functions.php:363
615
  msgctxt ""
616
  "Brief opening hours description which lists the days followed by the "
617
  "opening time. Example: Mo,Tu,We open from 9:00am"
618
  msgid "%s open from %s"
619
  msgstr ""
620
 
621
+ #: includes/template-functions.php:365
622
  msgctxt ""
623
  "Brief opening hours description which lists the days followed by the "
624
+ "opening and closing times. Example: Mo,Tu,We "
625
+ "9:00am&thinsp;&ndash;&thinsp;5:00pm"
626
+ msgid "%s %s&thinsp;&ndash;&thinsp;%s"
627
  msgstr ""
628
 
629
+ #: includes/template-functions.php:372
630
  msgctxt ""
631
  "Separator between multiple opening times in the brief opening hours. "
632
+ "Example: Mo,We 9:00 AM&thinsp;&ndash;&thinsp;5:00 PM; Tu,Th 10:00 "
633
+ "AM&thinsp;&ndash;&thinsp;5:00 PM"
634
  msgid "; "
635
  msgstr ""
636
 
637
+ #: includes/template-functions.php:416
638
+ msgctxt ""
639
+ "Separator between opening and closing times. Example: "
640
+ "9:00am&thinsp;&ndash;&thinsp;5:00pm"
641
+ msgid "&thinsp;&ndash;&thinsp;"
642
  msgstr ""
lib/class-gamajo-template-loader.php ADDED
@@ -0,0 +1,269 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Template Loader for Plugins.
4
+ *
5
+ * The Gamajo prefix has been replaced with Bpfwp to reduce plugin conflicts.
6
+ *
7
+ * @package Gamajo_Template_Loader
8
+ * @author Gary Jones
9
+ * @link http://github.com/GaryJones/Gamajo-Template-Loader
10
+ * @copyright 2013 Gary Jones
11
+ * @license GPL-2.0+
12
+ * @version 1.2.0
13
+ */
14
+
15
+ if ( ! class_exists( 'Bpfwp_Gamajo_Template_Loader' ) ) {
16
+
17
+ /**
18
+ * Template loader.
19
+ *
20
+ * Originally based on functions in Easy Digital Downloads (thanks Pippin!).
21
+ *
22
+ * When using in a plugin, create a new class that extends this one and just overrides the properties.
23
+ *
24
+ * @package Bpfwp_Gamajo_Template_Loader
25
+ * @author Gary Jones
26
+ */
27
+ class Bpfwp_Gamajo_Template_Loader {
28
+ /**
29
+ * Prefix for filter names.
30
+ *
31
+ * @since 1.0.0
32
+ *
33
+ * @var string
34
+ */
35
+ protected $filter_prefix = 'your_plugin';
36
+
37
+ /**
38
+ * Directory name where custom templates for this plugin should be found in the theme.
39
+ *
40
+ * For example: 'your-plugin-templates'.
41
+ *
42
+ * @since 1.0.0
43
+ *
44
+ * @var string
45
+ */
46
+ protected $theme_template_directory = 'plugin-templates';
47
+
48
+ /**
49
+ * Reference to the root directory path of this plugin.
50
+ *
51
+ * Can either be a defined constant, or a relative reference from where the subclass lives.
52
+ *
53
+ * e.g. YOUR_PLUGIN_TEMPLATE or plugin_dir_path( dirname( __FILE__ ) ); etc.
54
+ *
55
+ * @since 1.0.0
56
+ *
57
+ * @var string
58
+ */
59
+ protected $plugin_directory = 'YOUR_PLUGIN_DIR';
60
+
61
+ /**
62
+ * Directory name where templates are found in this plugin.
63
+ *
64
+ * Can either be a defined constant, or a relative reference from where the subclass lives.
65
+ *
66
+ * e.g. 'templates' or 'includes/templates', etc.
67
+ *
68
+ * @since 1.1.0
69
+ *
70
+ * @var string
71
+ */
72
+ protected $plugin_template_directory = 'templates';
73
+
74
+ /**
75
+ * Clean up template data.
76
+ *
77
+ * @since 1.2.0
78
+ */
79
+ public function __destruct() {
80
+ $this->unset_template_data();
81
+ }
82
+
83
+ /**
84
+ * Retrieve a template part.
85
+ *
86
+ * @since 1.0.0
87
+ *
88
+ * @param string $slug Template slug.
89
+ * @param string $name Optional. Template variation name. Default null.
90
+ * @param bool $load Optional. Whether to load template. Default true.
91
+ *
92
+ * @return string
93
+ */
94
+ public function get_template_part( $slug, $name = null, $load = true ) {
95
+ // Execute code for this part.
96
+ do_action( 'get_template_part_' . $slug, $slug, $name );
97
+
98
+ // Get files names of templates, for given slug and name.
99
+ $templates = $this->get_template_file_names( $slug, $name );
100
+
101
+ // Return the part that is found.
102
+ return $this->locate_template( $templates, $load, false );
103
+ }
104
+
105
+ /**
106
+ * Make custom data available to template.
107
+ *
108
+ * Data is available to the template as properties under the `$data` variable.
109
+ * i.e. A value provided here under `$data['foo']` is available as `$data->foo`.
110
+ *
111
+ * When an input key has a hyphen, you can use `$data->{foo-bar}` in the template.
112
+ *
113
+ * @since 1.2.0
114
+ *
115
+ * @param array $data Custom data for the template.
116
+ * @param string $var_name Optional. Variable under which the custom data is available in the template.
117
+ * Default is 'data'.
118
+ */
119
+ public function set_template_data( array $data, $var_name = 'data' ) {
120
+ global $wp_query;
121
+
122
+ $wp_query->query_vars[ $var_name ] = (object) $data;
123
+ }
124
+
125
+ /**
126
+ * Remove access to custom data in template.
127
+ *
128
+ * Good to use once the final template part has been requested.
129
+ *
130
+ * @since 1.2.0
131
+ */
132
+ public function unset_template_data() {
133
+ global $wp_query;
134
+
135
+ if ( isset( $wp_query->query_vars['data'] ) ) {
136
+ unset( $wp_query->query_vars['data'] );
137
+ }
138
+ }
139
+
140
+ /**
141
+ * Given a slug and optional name, create the file names of templates.
142
+ *
143
+ * @since 1.0.0
144
+ *
145
+ * @param string $slug Template slug.
146
+ * @param string $name Template variation name.
147
+ *
148
+ * @return array
149
+ */
150
+ protected function get_template_file_names( $slug, $name ) {
151
+ $templates = array();
152
+ if ( isset( $name ) ) {
153
+ $templates[] = $slug . '-' . $name . '.php';
154
+ }
155
+ $templates[] = $slug . '.php';
156
+
157
+ /**
158
+ * Allow template choices to be filtered.
159
+ *
160
+ * The resulting array should be in the order of most specific first, to least specific last.
161
+ * e.g. 0 => recipe-instructions.php, 1 => recipe.php
162
+ *
163
+ * @since 1.0.0
164
+ *
165
+ * @param array $templates Names of template files that should be looked for, for given slug and name.
166
+ * @param string $slug Template slug.
167
+ * @param string $name Template variation name.
168
+ */
169
+ return apply_filters( $this->filter_prefix . '_get_template_part', $templates, $slug, $name );
170
+ }
171
+
172
+ /**
173
+ * Retrieve the name of the highest priority template file that exists.
174
+ *
175
+ * Searches in the STYLESHEETPATH before TEMPLATEPATH so that themes which
176
+ * inherit from a parent theme can just overload one file. If the template is
177
+ * not found in either of those, it looks in the theme-compat folder last.
178
+ *
179
+ * @since 1.0.0
180
+ *
181
+ * @param string|array $template_names Template file(s) to search for, in order.
182
+ * @param bool $load If true the template file will be loaded if it is found.
183
+ * @param bool $require_once Whether to require_once or require. Default true.
184
+ * Has no effect if $load is false.
185
+ *
186
+ * @return string The template filename if one is located.
187
+ */
188
+ public function locate_template( $template_names, $load = false, $require_once = true ) {
189
+ // No file found yet.
190
+ $located = false;
191
+
192
+ // Remove empty entries.
193
+ $template_names = array_filter( (array) $template_names );
194
+ $template_paths = $this->get_template_paths();
195
+
196
+ // Try to find a template file.
197
+ foreach ( $template_names as $template_name ) {
198
+ // Trim off any slashes from the template name.
199
+ $template_name = ltrim( $template_name, '/' );
200
+
201
+ // Try locating this template file by looping through the template paths.
202
+ foreach ( $template_paths as $template_path ) {
203
+ if ( file_exists( $template_path . $template_name ) ) {
204
+ $located = $template_path . $template_name;
205
+ break 2;
206
+ }
207
+ }
208
+ }
209
+
210
+ if ( $load && $located ) {
211
+ load_template( $located, $require_once );
212
+ }
213
+
214
+ return $located;
215
+ }
216
+
217
+ /**
218
+ * Return a list of paths to check for template locations.
219
+ *
220
+ * Default is to check in a child theme (if relevant) before a parent theme, so that themes which inherit from a
221
+ * parent theme can just overload one file. If the template is not found in either of those, it looks in the
222
+ * theme-compat folder last.
223
+ *
224
+ * @since 1.0.0
225
+ *
226
+ * @return mixed|void
227
+ */
228
+ protected function get_template_paths() {
229
+ $theme_directory = trailingslashit( $this->theme_template_directory );
230
+
231
+ $file_paths = array(
232
+ 10 => trailingslashit( get_template_directory() ) . $theme_directory,
233
+ 100 => $this->get_templates_dir(),
234
+ );
235
+
236
+ // Only add this conditionally, so non-child themes don't redundantly check active theme twice.
237
+ if ( is_child_theme() ) {
238
+ $file_paths[1] = trailingslashit( get_stylesheet_directory() ) . $theme_directory;
239
+ }
240
+
241
+ /**
242
+ * Allow ordered list of template paths to be amended.
243
+ *
244
+ * @since 1.0.0
245
+ *
246
+ * @param array $var Default is directory in child theme at index 1, parent theme at 10, and plugin at 100.
247
+ */
248
+ $file_paths = apply_filters( $this->filter_prefix . '_template_paths', $file_paths );
249
+
250
+ // Sort the file paths based on priority.
251
+ ksort( $file_paths, SORT_NUMERIC );
252
+
253
+ return array_map( 'trailingslashit', $file_paths );
254
+ }
255
+
256
+ /**
257
+ * Return the path to the templates directory in this plugin.
258
+ *
259
+ * May be overridden in subclass.
260
+ *
261
+ * @since 1.0.0
262
+ *
263
+ * @return string
264
+ */
265
+ protected function get_templates_dir() {
266
+ return trailingslashit( $this->plugin_directory ) . $this->plugin_template_directory;
267
+ }
268
+ }
269
+ }
readme.txt CHANGED
@@ -3,9 +3,9 @@ Contributors: NateWr
3
  Author URI: https://github.com/NateWr
4
  Plugin URL: http://themeofthecrop.com
5
  Requires at Least: 3.9
6
- Tested Up To: 4.5
7
- Tags: business profile, address, google map, schema, contact, phone, address, seo
8
- Stable tag: 1.0.9
9
  License: GPLv2 or later
10
  Donate link: http://themeofthecrop.com
11
 
@@ -25,9 +25,9 @@ Add your business contact details to your site with seo-friendly Schema.org mark
25
 
26
  Schema.org markup helps search engines like Google discover your address, phone number and opening hours so that they can display them with your listing on Google.
27
 
28
- **Sorry, it does not support multiple locations.**
29
 
30
- This plugin is part of a group of plugins for restaurants. Check out the [Food and Drink Menu](http://wordpress.org/plugins/food-and-drink-menu/), [Restaurant Reservations](http://wordpress.org/plugins/restaurant-reservations/) and [Good Reviews for WordPress](http://wordpress.org/plugins/good-reviews-wp/) plugins as well.
31
 
32
  = How to use =
33
 
@@ -35,7 +35,7 @@ View the [help guide](http://doc.themeofthecrop.com/plugins/business-profile/?ut
35
 
36
  = Developers =
37
 
38
- This plugin is packed with hooks so you can extend it as needed. Development takes place on [GitHub](https://github.com/NateWr/business-profile/), so fork it up.
39
 
40
  == Installation ==
41
 
@@ -49,9 +49,18 @@ This plugin is packed with hooks so you can extend it as needed. Development tak
49
  1. Display a full contact card on the front-end with the shortcode [contact-card] or use the widget to add it to a sidebar.
50
  2. An easy-to-use form lets you add all of the information, locate the correct map coordinates and set up your opening hours.
51
  3. Choose what information to display with the widget, or check out the shortcode attributes in the help document included.
 
52
 
53
  == Changelog ==
54
 
 
 
 
 
 
 
 
 
55
  = 1.0.9 (2016-02-12) =
56
  * Fix: compatibility with wp-cli
57
  * Fix: allow short weekday names to be translated
@@ -101,6 +110,9 @@ This plugin is packed with hooks so you can extend it as needed. Development tak
101
 
102
  == Upgrade Notice ==
103
 
 
 
 
104
  = 1.0.9 =
105
  This update fixes wp-cli compatibility and adds a number of useful development filters/features for interacting with the map objects.
106
 
3
  Author URI: https://github.com/NateWr
4
  Plugin URL: http://themeofthecrop.com
5
  Requires at Least: 3.9
6
+ Tested Up To: 4.5.2
7
+ Tags: business profile, seo, local seo, schema, address, google map, contact, phone
8
+ Stable tag: 1.1
9
  License: GPLv2 or later
10
  Donate link: http://themeofthecrop.com
11
 
25
 
26
  Schema.org markup helps search engines like Google discover your address, phone number and opening hours so that they can display them with your listing on Google.
27
 
28
+ **Supports [multi-location businesses](http://doc.themeofthecrop.com/plugins/business-profile/user/getting-started/locations) with a custom Locations post type.**
29
 
30
+ This plugin is part of a group of plugins for restaurants. Check out the [Restaurant Reservations](http://wordpress.org/plugins/restaurant-reservations/), [Food and Drink Menu](http://wordpress.org/plugins/food-and-drink-menu/), and [Good Reviews for WordPress](http://wordpress.org/plugins/good-reviews-wp/) plugins as well.
31
 
32
  = How to use =
33
 
35
 
36
  = Developers =
37
 
38
+ This plugin is packed with templates and hooks so you can extend it as needed. Read the [developer documentation](http://doc.themeofthecrop.com/plugins/business-profile/developer/). Development takes place on [GitHub](https://github.com/NateWr/business-profile/), so fork it up.
39
 
40
  == Installation ==
41
 
49
  1. Display a full contact card on the front-end with the shortcode [contact-card] or use the widget to add it to a sidebar.
50
  2. An easy-to-use form lets you add all of the information, locate the correct map coordinates and set up your opening hours.
51
  3. Choose what information to display with the widget, or check out the shortcode attributes in the help document included.
52
+ 4. Optional multi-location support to easily display all of your locations.
53
 
54
  == Changelog ==
55
 
56
+ = 1.1 (2016-06-20) =
57
+ * Add: multi-location support
58
+ * Add: filter to adjust available schema types
59
+ * Add: templates for contact cards and opening hours
60
+ * Add: helper functions for templating
61
+ * Add: add_theme_support() args for disabling scripts, styles and append to content
62
+ * Update: implement WP coding standards. h/t @robnue
63
+
64
  = 1.0.9 (2016-02-12) =
65
  * Fix: compatibility with wp-cli
66
  * Fix: allow short weekday names to be translated
110
 
111
  == Upgrade Notice ==
112
 
113
+ = 1.1 =
114
+ This major update adds support for multiple locations, refactors the codebase to follow WP coding guidelines, and adds several templates and helper functions for customization.
115
+
116
  = 1.0.9 =
117
  This update fixes wp-cli compatibility and adds a number of useful development filters/features for interacting with the map objects.
118
 
screenshot-4.png ADDED
Binary file
templates/contact-card.php ADDED
@@ -0,0 +1,100 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Template for a contact card
4
+ *
5
+ * Copy this template into your theme to modify the output of the contact card.
6
+ * The template should sit in your theme here:
7
+ *
8
+ * /wp-content/themes/your-theme/business-profile-templates/contact-card.php
9
+ *
10
+ * You can also add custom templates for each location by creating a template
11
+ * file with the location's ID, eg:
12
+ *
13
+ * /wp-content/themes/your-theme/business-profile-templates/contact-card-123.php
14
+ *
15
+ * By default, the template uses a filtered callback system defined in
16
+ * bpwfwp_print_contact_card(), which you'll find in the plugins'
17
+ * includes/template-functions.php. This structure allows it a certain kind of
18
+ * "hands-off" flexibility for third-party integrations. Plugins can hook into
19
+ * `bpwfwp_component_callbacks` to add or remove content without overriding or
20
+ * effecting existing content.
21
+ *
22
+ * Individual settings can be accessed using the bpfwp_setting(). Example:
23
+ *
24
+ * <?php bpfwp_setting( 'address' ); ?>
25
+ *
26
+ * You can also pass a location ID to bpfwp_setting(). Example:
27
+ *
28
+ * <?php bpfwp_setting( 'address', 123 ); ?>
29
+ *
30
+ * However, ensuring you have complete Schema.org markup can be especially
31
+ * difficult for some things, like Opening Hours. There are a number of template
32
+ * functions at your disposal to help you print details with schema markup.
33
+ * You'll find these at /includes/template-functions.php. Example:
34
+ *
35
+ * <?php bpwfwp_print_address(); ?>
36
+ *
37
+ * These also support a location. Example:
38
+ *
39
+ * <?php bpwfwp_print_address( 123 ); ?>
40
+ *
41
+ * This template can be loaded automatically in a post loop, from a shortcode
42
+ * or via a widget (or you can use bpwfwp_print_contact_card() to print it
43
+ * anywhere you want). For that reason, the location requested may not be the
44
+ * same as the global post (eg - get_the_ID()). To ensure compatibility with the
45
+ * plugin's [contact-card] shortcode and Contact Card widget, you should use
46
+ * bpfwp_setting() to retrieve any possible location post ID. Example:
47
+ *
48
+ * <?php
49
+ * $location = bpfwp_get_display( 'location' );
50
+ * bpfwp_setting( 'address', $location );
51
+ * ?>
52
+ *
53
+ * The $bpfwp_controller->display_settings array also contains information on
54
+ * any content that has been hidden with shortcode attributes or widget options.
55
+ * This allows a value to be printed for proper schema markup without being
56
+ * displayed. You should check the bool values with the bpfwp_get_display()
57
+ * helper function before printing. Example:
58
+ *
59
+ * <?php
60
+ * $location = bpfwp_get_display( 'location' );
61
+ * if ( bpfwp_get_display( 'show_address' ) ) {
62
+ * ?>
63
+ * <div itemprop="address">
64
+ * <?php bpfwp_setting( 'address', $location ); ?>
65
+ * </div>
66
+ * <?php
67
+ * }
68
+ * ?>
69
+ *
70
+ * If you use the template functions to have the schema markup printed for you,
71
+ * they will take account of these display settings and use hidden meta where
72
+ * appropriate.
73
+ *
74
+ * If you want to explicitly set the visibility of a type of information before
75
+ * calling it's template function, you can do that. For instance, to show only
76
+ * the brief opening hours, you can do the following:
77
+ *
78
+ * <?php
79
+ * $location = bpfwp_get_display( 'location' );
80
+ * bpfwp_set_display( 'show_opening_hours_brief', true );
81
+ * bpwfwp_print_opening_hours( $location );
82
+ * ?>
83
+ *
84
+ * Google provides a Structured Data Testing Tool which is useful for validating
85
+ * your schema markup once you've changed it.
86
+ *
87
+ * https://search.google.com/structured-data/testing-tool/u/0/
88
+ *
89
+ * Happy theming!
90
+ *
91
+ * @package BusinessProfile
92
+ * @copyright Copyright (c) 2016, Theme of the Crop
93
+ * @license GPL-2.0+
94
+ * @since 1.1.0
95
+ */
96
+ ?>
97
+
98
+ <address class="bp-contact-card" itemscope itemtype="http://schema.org/<?php echo bpfwp_setting( 'schema-type', bpfwp_get_display( 'location' ) ); ?>">
99
+ <?php foreach ( $data as $data => $callback ) { call_user_func( $callback, bpfwp_get_display( 'location' ) ); } ?>
100
+ </address>
templates/opening-hours.php ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Template for displaying the opening hours
4
+ *
5
+ * This template does not perform the Schema.org markup. That is printed as a
6
+ * series of metatags as part of the bpwfwp_print_opening_hours() template
7
+ * function.
8
+ *
9
+ * For full details about theming, see /templates/contact-card.php
10
+ *
11
+ * Happy theming!
12
+ *
13
+ * @package BusinessProfile
14
+ * @copyright Copyright (c) 2016, Theme of the Crop
15
+ * @license GPL-2.0+
16
+ * @since 1.1.0
17
+ */
18
+ ?>
19
+
20
+ <div class="bp-opening-hours">
21
+ <span class="bp-title"><?php _e( 'Opening Hours', 'business-profile' ); ?></span>
22
+ <?php foreach ( $data->weekday_hours as $weekday => $times ) : ?>
23
+ <div class="bp-weekday">
24
+ <span class="bp-weekday-name bp-weekday-<?php echo $weekday; ?>"><?php echo $data->weekday_names[$weekday]; ?></span>
25
+ <span class="bp-times">
26
+ <?php foreach ( $times as $time ) : ?>
27
+ <span class="bp-time"><?php echo $time; ?></span>
28
+ <?php endforeach; ?>
29
+ </span>
30
+ </div>
31
+ <?php endforeach; ?>
32
+ </div>