css
3 years ago
images
3 years ago
js
3 years ago
admin.php
3 years ago
class-grunion-contact-form-endpoint.php
1 year ago
grunion-contact-form.php
3 years ago
grunion-editor-view.php
4 years ago
grunion-form-view.php
3 years ago
grunion-response-email-template.php
3 years ago
grunion-editor-view.php
327 lines
| 1 | <?php // phpcs:ignore WordPress.Files.FileName.InvalidClassFileName |
| 2 | |
| 3 | use Automattic\Jetpack\Assets; |
| 4 | |
| 5 | /* |
| 6 | * A prototype to allow inline editing / editor views for contact forms.\ |
| 7 | * |
| 8 | * Originally developed in: https://github.com/automattic/gm2016-grunion-editor |
| 9 | * Authors: Michael Arestad, Andrew Ozz, and George Stephanis |
| 10 | */ |
| 11 | |
| 12 | /** |
| 13 | * Grunion editor view class. |
| 14 | */ |
| 15 | class Grunion_Editor_View { |
| 16 | |
| 17 | /** |
| 18 | * Add hooks according to screen. |
| 19 | * |
| 20 | * @param WP_Screen $screen Data about current screen. |
| 21 | */ |
| 22 | public static function add_hooks( $screen ) { |
| 23 | if ( isset( $screen->base ) && 'post' === $screen->base ) { |
| 24 | add_action( 'admin_notices', array( __CLASS__, 'handle_editor_view_js' ) ); |
| 25 | add_action( 'admin_head', array( __CLASS__, 'admin_head' ) ); |
| 26 | } |
| 27 | } |
| 28 | |
| 29 | /** |
| 30 | * Admin header. |
| 31 | */ |
| 32 | public static function admin_head() { |
| 33 | remove_action( 'media_buttons', 'grunion_media_button', 999 ); |
| 34 | add_action( 'media_buttons', array( __CLASS__, 'grunion_media_button' ), 999 ); |
| 35 | } |
| 36 | |
| 37 | /** |
| 38 | * Render the grunion media button. |
| 39 | */ |
| 40 | public static function grunion_media_button() { |
| 41 | $title = __( 'Add Contact Form', 'jetpack' ); |
| 42 | ?> |
| 43 | |
| 44 | <button type="button" id="insert-jetpack-contact-form" class="button" title="<?php echo esc_attr( $title ); ?>" href="javascript:;"> |
| 45 | <span class="jetpack-contact-form-icon"></span> |
| 46 | <?php echo esc_html( $title ); ?> |
| 47 | </button> |
| 48 | |
| 49 | <?php |
| 50 | } |
| 51 | |
| 52 | /** |
| 53 | * Get external plugins. |
| 54 | * |
| 55 | * @param array $plugin_array - the plugin array. |
| 56 | * |
| 57 | * @return array |
| 58 | */ |
| 59 | public static function mce_external_plugins( $plugin_array ) { |
| 60 | $plugin_array['grunion_form'] = Assets::get_file_url_for_environment( |
| 61 | '_inc/build/contact-form/js/tinymce-plugin-form-button.min.js', |
| 62 | 'modules/contact-form/js/tinymce-plugin-form-button.js' |
| 63 | ); |
| 64 | return $plugin_array; |
| 65 | } |
| 66 | |
| 67 | /** |
| 68 | * MCE buttons. |
| 69 | * |
| 70 | * @param array $buttons - the buttons. |
| 71 | * |
| 72 | * @return array |
| 73 | */ |
| 74 | public static function mce_buttons( $buttons ) { |
| 75 | $size = count( $buttons ); |
| 76 | $buttons1 = array_slice( $buttons, 0, $size - 1 ); |
| 77 | $buttons2 = array_slice( $buttons, $size - 1 ); |
| 78 | return array_merge( |
| 79 | $buttons1, |
| 80 | array( 'grunion' ), |
| 81 | $buttons2 |
| 82 | ); |
| 83 | } |
| 84 | |
| 85 | /** |
| 86 | * WordPress Shortcode Editor View JS Code |
| 87 | */ |
| 88 | public static function handle_editor_view_js() { |
| 89 | add_action( 'admin_print_footer_scripts', array( __CLASS__, 'editor_view_js_templates' ), 1 ); |
| 90 | add_filter( 'mce_external_plugins', array( __CLASS__, 'mce_external_plugins' ) ); |
| 91 | add_filter( 'mce_buttons', array( __CLASS__, 'mce_buttons' ) ); |
| 92 | |
| 93 | wp_enqueue_style( 'grunion-editor-ui', plugins_url( 'css/editor-ui.css', __FILE__ ), array(), JETPACK__VERSION ); |
| 94 | wp_style_add_data( 'grunion-editor-ui', 'rtl', 'replace' ); |
| 95 | wp_enqueue_script( |
| 96 | 'grunion-editor-view', |
| 97 | Assets::get_file_url_for_environment( |
| 98 | '_inc/build/contact-form/js/editor-view.min.js', |
| 99 | 'modules/contact-form/js/editor-view.js' |
| 100 | ), |
| 101 | array( 'wp-util', 'jquery', 'quicktags' ), |
| 102 | JETPACK__VERSION, |
| 103 | true |
| 104 | ); |
| 105 | wp_localize_script( |
| 106 | 'grunion-editor-view', |
| 107 | 'grunionEditorView', |
| 108 | array( |
| 109 | 'inline_editing_style' => plugins_url( 'css/editor-inline-editing-style.css', __FILE__ ), |
| 110 | 'inline_editing_style_rtl' => plugins_url( 'css/editor-inline-editing-style-rtl.css', __FILE__ ), |
| 111 | 'dashicons_css_url' => includes_url( 'css/dashicons.css' ), |
| 112 | 'default_form' => '[contact-field label="' . __( 'Name', 'jetpack' ) . '" type="name" required="true" /]' . |
| 113 | '[contact-field label="' . __( 'Email', 'jetpack' ) . '" type="email" required="true" /]' . |
| 114 | '[contact-field label="' . __( 'Website', 'jetpack' ) . '" type="url" /]' . |
| 115 | '[contact-field label="' . __( 'Message', 'jetpack' ) . '" type="textarea" /]', |
| 116 | 'labels' => array( |
| 117 | 'submit_button_text' => __( 'Submit', 'jetpack' ), |
| 118 | /** This filter is documented in modules/contact-form/grunion-contact-form.php */ |
| 119 | 'required_field_text' => apply_filters( 'jetpack_required_field_text', __( '(required)', 'jetpack' ) ), |
| 120 | 'edit_close_ays' => __( 'Are you sure you\'d like to stop editing this form without saving your changes?', 'jetpack' ), |
| 121 | 'quicktags_label' => __( 'contact form', 'jetpack' ), |
| 122 | 'tinymce_label' => __( 'Add contact form', 'jetpack' ), |
| 123 | ), |
| 124 | ) |
| 125 | ); |
| 126 | |
| 127 | add_editor_style( plugin_dir_url( __FILE__ ) . 'css/editor-style.css' ); |
| 128 | } |
| 129 | |
| 130 | /** |
| 131 | * JS Templates. |
| 132 | */ |
| 133 | public static function editor_view_js_templates() { |
| 134 | ?> |
| 135 | <script type="text/html" id="tmpl-grunion-contact-form"> |
| 136 | <form class="card jetpack-contact-form-shortcode-preview" action='#' method='post' class='contact-form commentsblock' onsubmit="return false;"> |
| 137 | {{{ data.body }}} |
| 138 | <p class='contact-submit'> |
| 139 | <input type='submit' value='{{ data.submit_button_text }}' class='pushbutton-wide'/> |
| 140 | </p> |
| 141 | </form> |
| 142 | </script> |
| 143 | |
| 144 | <script type="text/html" id="tmpl-grunion-field-email"> |
| 145 | <div> |
| 146 | <label for='{{ data.id }}' class='grunion-field-label email'>{{ data.label }}<# if ( data.required ) print( " <span>" + data.required + "</span>" ) #></label> |
| 147 | <input type='email' name='{{ data.id }}' id='{{ data.id }}' value='{{ data.value }}' class='{{ data.class }}' placeholder='{{ data.placeholder }}' /> |
| 148 | </div> |
| 149 | </script> |
| 150 | |
| 151 | <script type="text/html" id="tmpl-grunion-field-telephone"> |
| 152 | <div> |
| 153 | <label for='{{ data.id }}' class='grunion-field-label telephone'>{{ data.label }}<# if ( data.required ) print( " <span>" + data.required + "</span>" ) #></label> |
| 154 | <input type='tel' name='{{ data.id }}' id='{{ data.id }}' value='{{ data.value }}' class='{{ data.class }}' placeholder='{{ data.placeholder }}' /> |
| 155 | </div> |
| 156 | </script> |
| 157 | |
| 158 | <script type="text/html" id="tmpl-grunion-field-textarea"> |
| 159 | <div> |
| 160 | <label for='contact-form-comment-{{ data.id }}' class='grunion-field-label textarea'>{{ data.label }}<# if ( data.required ) print( " <span>" + data.required + "</span>" ) #></label> |
| 161 | <textarea name='{{ data.id }}' id='contact-form-comment-{{ data.id }}' rows='20' class='{{ data.class }}' placeholder='{{ data.placeholder }}'>{{ data.value }}</textarea> |
| 162 | </div> |
| 163 | </script> |
| 164 | |
| 165 | <script type="text/html" id="tmpl-grunion-field-radio"> |
| 166 | <div> |
| 167 | <label class='grunion-field-label'>{{ data.label }}<# if ( data.required ) print( " <span>" + data.required + "</span>" ) #></label> |
| 168 | <# _.each( data.options, function( option ) { #> |
| 169 | <label class='grunion-radio-label radio'> |
| 170 | <input type='radio' name='{{ data.id }}' value='{{ option }}' class="{{ data.class }}" <# if ( option === data.value ) print( "checked='checked'" ) #> /> |
| 171 | <span>{{ option }}</span> |
| 172 | </label> |
| 173 | <# }); #> |
| 174 | <div class='clear-form'></div> |
| 175 | </div> |
| 176 | </script> |
| 177 | |
| 178 | <script type="text/html" id="tmpl-grunion-field-checkbox"> |
| 179 | <div> |
| 180 | <label class='grunion-field-label checkbox'> |
| 181 | <input type='checkbox' name='{{ data.id }}' value='<?php esc_attr__( 'Yes', 'jetpack' ); ?>' class="{{ data.class }}" <# if ( data.value ) print( 'checked="checked"' ) #> /> |
| 182 | <span>{{ data.label }}</span><# if ( data.required ) print( " <span>" + data.required + "</span>" ) #> |
| 183 | </label> |
| 184 | <div class='clear-form'></div> |
| 185 | </div> |
| 186 | </script> |
| 187 | |
| 188 | <script type="text/html" id="tmpl-grunion-field-checkbox-multiple"> |
| 189 | <div> |
| 190 | <label class='grunion-field-label'>{{ data.label }}<# if ( data.required ) print( " <span>" + data.required + "</span>" ) #></label> |
| 191 | <# _.each( data.options, function( option ) { #> |
| 192 | <label class='grunion-checkbox-multiple-label checkbox-multiple'> |
| 193 | <input type='checkbox' name='{{ data.id }}[]' value='{{ option }}' class="{{ data.class }}" <# if ( option === data.value || _.contains( data.value, option ) ) print( "checked='checked'" ) #> /> |
| 194 | <span>{{ option }}</span> |
| 195 | </label> |
| 196 | <# }); #> |
| 197 | <div class='clear-form'></div> |
| 198 | </div> |
| 199 | </script> |
| 200 | |
| 201 | <script type="text/html" id="tmpl-grunion-field-select"> |
| 202 | <div> |
| 203 | <label for='{{ data.id }}' class='grunion-field-label select'>{{ data.label }}<# if ( data.required ) print( " <span>" + data.required + "</span>" ) #></label> |
| 204 | <select name='{{ data.id }}' id='{{ data.id }}' class="{{ data.class }}"> |
| 205 | <# _.each( data.options, function( option ) { #> |
| 206 | <option <# if ( option === data.value ) print( "selected='selected'" ) #>>{{ option }}</option> |
| 207 | <# }); #> |
| 208 | </select> |
| 209 | </div> |
| 210 | </script> |
| 211 | |
| 212 | <script type="text/html" id="tmpl-grunion-field-date"> |
| 213 | <div> |
| 214 | <label for='{{ data.id }}' class='grunion-field-label {{ data.type }}'>{{ data.label }}<# if ( data.required ) print( " <span>" + data.required + "</span>" ) #></label> |
| 215 | <input type='text' name='{{ data.id }}' id='{{ data.id }}' value='{{ data.value }}' class="{{ data.class }}" /> |
| 216 | </div> |
| 217 | </script> |
| 218 | |
| 219 | <script type="text/html" id="tmpl-grunion-field-text"> |
| 220 | <div> |
| 221 | <label for='{{ data.id }}' class='grunion-field-label {{ data.type }}'>{{ data.label }}<# if ( data.required ) print( " <span>" + data.required + "</span>" ) #></label> |
| 222 | <input type='text' name='{{ data.id }}' id='{{ data.id }}' value='{{ data.value }}' class='{{ data.class }}' placeholder='{{ data.placeholder }}' /> |
| 223 | </div> |
| 224 | </script> |
| 225 | |
| 226 | <script type="text/html" id="tmpl-grunion-field-url"> |
| 227 | <div> |
| 228 | <label for='{{ data.id }}' class='grunion-field-label {{ data.type }}'>{{ data.label }}<# if ( data.required ) print( " <span>" + data.required + "</span>" ) #></label> |
| 229 | <input type='url' name='{{ data.id }}' id='{{ data.id }}' value='{{ data.value }}' class='{{ data.class }}' placeholder='{{ data.placeholder }}' /> |
| 230 | </div> |
| 231 | </script> |
| 232 | |
| 233 | |
| 234 | <script type="text/html" id="tmpl-grunion-field-edit"> |
| 235 | <div class="card is-compact grunion-field-edit grunion-field-{{ data.type }}" aria-label="<?php esc_attr_e( 'Form Field', 'jetpack' ); ?>"> |
| 236 | <label class="grunion-name"> |
| 237 | <span><?php esc_html_e( 'Field Label', 'jetpack' ); ?></span> |
| 238 | <input type="text" name="label" placeholder="<?php esc_attr_e( 'Label', 'jetpack' ); ?>" value="{{ data.label }}"/> |
| 239 | </label> |
| 240 | |
| 241 | <?php |
| 242 | $grunion_field_types = array( |
| 243 | 'text' => __( 'Text', 'jetpack' ), |
| 244 | 'name' => __( 'Name', 'jetpack' ), |
| 245 | 'email' => __( 'Email', 'jetpack' ), |
| 246 | 'url' => __( 'Website', 'jetpack' ), |
| 247 | 'textarea' => __( 'Textarea', 'jetpack' ), |
| 248 | 'checkbox' => __( 'Checkbox', 'jetpack' ), |
| 249 | 'checkbox-multiple' => __( 'Checkbox with Multiple Items', 'jetpack' ), |
| 250 | 'select' => __( 'Drop down', 'jetpack' ), |
| 251 | 'radio' => __( 'Radio', 'jetpack' ), |
| 252 | 'date' => __( 'Date', 'jetpack' ), |
| 253 | ); |
| 254 | ?> |
| 255 | <div class="grunion-type-options"> |
| 256 | <label class="grunion-type"> |
| 257 | <?php esc_html_e( 'Field Type', 'jetpack' ); ?> |
| 258 | <select name="type"> |
| 259 | <?php foreach ( $grunion_field_types as $type => $label ) : ?> |
| 260 | <option <# if ( '<?php echo esc_js( $type ); ?>' === data.type ) print( "selected='selected'" ) #> value="<?php echo esc_attr( $type ); ?>"> |
| 261 | <?php echo esc_html( $label ); ?> |
| 262 | </option> |
| 263 | <?php endforeach; ?> |
| 264 | </select> |
| 265 | </label> |
| 266 | |
| 267 | <label class="grunion-required"> |
| 268 | <input type="checkbox" name="required" value="1" <# if ( data.required ) print( 'checked="checked"' ) #> /> |
| 269 | <span><?php esc_html_e( 'Required?', 'jetpack' ); ?></span> |
| 270 | </label> |
| 271 | </div> |
| 272 | |
| 273 | <label class="grunion-options"> |
| 274 | <?php esc_html_e( 'Options', 'jetpack' ); ?> |
| 275 | <ol> |
| 276 | <# if ( data.options ) { #> |
| 277 | <# _.each( data.options, function( option ) { #> |
| 278 | <li><input type="text" name="option" value="{{ option }}" /> <a class="delete-option" href="javascript:;"><span class="screen-reader-text"><?php esc_html_e( 'Delete Option', 'jetpack' ); ?></span></a></li> |
| 279 | <# }); #> |
| 280 | <# } else { #> |
| 281 | <li><input type="text" name="option" /> <a class="delete-option" href="javascript:;"><span class="screen-reader-text"><?php esc_html_e( 'Delete Option', 'jetpack' ); ?></span></a></li> |
| 282 | <li><input type="text" name="option" /> <a class="delete-option" href="javascript:;"><span class="screen-reader-text"><?php esc_html_e( 'Delete Option', 'jetpack' ); ?></span></a></li> |
| 283 | <li><input type="text" name="option" /> <a class="delete-option" href="javascript:;"><span class="screen-reader-text"><?php esc_html_e( 'Delete Option', 'jetpack' ); ?></span></a></li> |
| 284 | <# } #> |
| 285 | <li><a class="add-option" href="javascript:;"><?php esc_html_e( 'Add new option...', 'jetpack' ); ?></a></li> |
| 286 | </ol> |
| 287 | </label> |
| 288 | |
| 289 | <a href="javascript:;" class="delete-field"><span class="screen-reader-text"><?php esc_html_e( 'Delete Field', 'jetpack' ); ?></span></a> |
| 290 | </div> |
| 291 | </script> |
| 292 | |
| 293 | <script type="text/html" id="tmpl-grunion-field-edit-option"> |
| 294 | <li><input type="text" name="option" /> <a class="delete-option" href="javascript:;"><span class="screen-reader-text"><?php esc_html_e( 'Delete Option', 'jetpack' ); ?></span></a></li> |
| 295 | </script> |
| 296 | |
| 297 | <script type="text/html" id="tmpl-grunion-editor-inline"> |
| 298 | <h1 id="form-settings-header" class="grunion-section-header"><?php esc_html_e( 'Contact form information', 'jetpack' ); ?></h1> |
| 299 | <section class="card grunion-form-settings" aria-labelledby="form-settings-header"> |
| 300 | <label><?php esc_html_e( 'What would you like the subject of the email to be?', 'jetpack' ); ?> |
| 301 | <input type="text" name="subject" value="{{ data.subject }}" /> |
| 302 | </label> |
| 303 | <label><?php esc_html_e( 'Which email address should we send the submissions to?', 'jetpack' ); ?> |
| 304 | <input type="text" name="to" value="{{ data.to }}" /> |
| 305 | </label> |
| 306 | </section> |
| 307 | <h1 id="form-fields-header" class="grunion-section-header"><?php esc_html_e( 'Contact form fields', 'jetpack' ); ?></h1> |
| 308 | <section class="grunion-fields" aria-labelledby="form-fields-header"> |
| 309 | {{{ data.fields }}} |
| 310 | </section> |
| 311 | <section class="grunion-controls"> |
| 312 | <?php submit_button( esc_html__( 'Add Field', 'jetpack' ), 'secondary', 'add-field', false ); ?> |
| 313 | |
| 314 | <div class="grunion-update-controls"> |
| 315 | <?php submit_button( esc_html__( 'Cancel', 'jetpack' ), 'delete', 'cancel', false ); ?> |
| 316 | <?php submit_button( esc_html__( 'Update Form', 'jetpack' ), 'primary', 'submit', false ); ?> |
| 317 | </div> |
| 318 | </section> |
| 319 | </script> |
| 320 | |
| 321 | </div> |
| 322 | <?php |
| 323 | } |
| 324 | } |
| 325 | |
| 326 | add_action( 'current_screen', array( 'Grunion_Editor_View', 'add_hooks' ) ); |
| 327 |