├── .gitignore ├── Gruntfile.js ├── Gulpfile.js ├── README.md ├── assets ├── css │ └── connector-ui.css └── js │ ├── cf-connected-ajax.js │ ├── connector-ui.js │ └── jsPlumb-1.7.10-min.js ├── composer.json ├── composer.lock ├── how-to-grunt.md ├── includes ├── calcdefaults.php ├── functions.php ├── partial.php ├── ptrack.php └── templates │ ├── back_field.php │ ├── connection-builder.php │ ├── next_field.php │ └── partials.php ├── languages ├── cf-form-connector.pot ├── fr_FR.mo └── fr_FR.po ├── naming-conventions.txt ├── package.json ├── plugin.php ├── readme.txt └── releases ├── cf-connected-forms-0.2.1.zip ├── cf-connected-forms-1.0.0.zip ├── cf-connected-forms-1.0.1.zip ├── cf-connected-forms-1.0.2-b-1.zip ├── cf-connected-forms-1.0.2.zip ├── cf-connected-forms-1.0.3.zip ├── cf-connected-forms-1.0.4-b1.zip ├── cf-connected-forms-1.0.4.zip ├── cf-connected-forms-1.0.5-rc1.zip ├── cf-connected-forms-1.0.5.zip ├── cf-connected-forms-1.0.6.zip ├── cf-connected-forms-1.0.7-b-1.zip ├── cf-connected-forms-1.0.7.zip ├── cf-connected-forms-1.0.8.zip ├── cf-connected-forms-1.1.0-b-1.zip ├── cf-connected-forms-1.1.0.zip ├── cf-connected-forms-1.1.1-b-1.zip ├── cf-connected-forms-1.1.1-rc-1.zip ├── cf-connected-forms-1.1.1.zip ├── cf-connected-forms-1.2.0.zip ├── cf-connected-forms-1.2.1-b-1.zip ├── cf-connected-forms-1.2.1.zip ├── cf-connected-forms-1.2.2-b-1.zip ├── cf-connected-forms-1.2.2.zip ├── cf-connected-forms-1.3.0-b-1.zip ├── cf-connected-forms-1.3.0-b-2.zip ├── cf-form-connector-0.1.0.zip └── cf-form-connector-0.2.0.zip /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | vendor 3 | assets/js/cf-connected-ajax.min.js 4 | assets/js/connector-ui.min.js -------------------------------------------------------------------------------- /Gruntfile.js: -------------------------------------------------------------------------------- 1 | module.exports = function (grunt) { 2 | 3 | 4 | // Project configuration. 5 | grunt.initConfig({ 6 | pkg : grunt.file.readJSON( 'package.json' ), 7 | shell: { 8 | composer: { 9 | command: 'composer update' 10 | }, 11 | gulp: { 12 | command: 'gulp' 13 | } 14 | }, 15 | clean: { 16 | post_build: [ 17 | 'build/' 18 | ], 19 | pre_compress: [ 20 | 'build/releases' 21 | ] 22 | }, 23 | run: { 24 | tool: { 25 | cmd: './composer' 26 | } 27 | }, 28 | copy: { 29 | build: { 30 | options : { 31 | mode :true 32 | }, 33 | src: [ 34 | '**', 35 | '!node_modules/**', 36 | '!releases', 37 | '!releases/**', 38 | '!.git/**', 39 | '!Gruntfile.js', 40 | '!package.json', 41 | '!.gitignore', 42 | '!.gitmodules', 43 | '!.gitattributes', 44 | '!composer.lock', 45 | '!naming-conventions.txt', 46 | '!how-to-grunt.md' 47 | ], 48 | dest: 'build/<%= pkg.name %>/' 49 | } 50 | }, 51 | compress: { 52 | main: { 53 | options: { 54 | mode: 'zip', 55 | archive: 'releases/<%= pkg.name %>-<%= pkg.version %>.zip' 56 | }, 57 | expand: true, 58 | cwd: 'build/', 59 | src: [ 60 | '**/*', 61 | '!build/*' 62 | ] 63 | } 64 | }, 65 | gitadd: { 66 | add_zip: { 67 | options: { 68 | force: true 69 | }, 70 | files: { 71 | src: [ 'releases/<%= pkg.name %>-<%= pkg.version %>.zip' ] 72 | } 73 | } 74 | }, 75 | gittag: { 76 | addtag: { 77 | options: { 78 | tag: '<%= pkg.version %>', 79 | message: 'Version <%= pkg.version %>' 80 | } 81 | } 82 | }, 83 | gitcommit: { 84 | commit: { 85 | options: { 86 | message: 'Version <%= pkg.version %>', 87 | noVerify: true, 88 | noStatus: false, 89 | allowEmpty: true 90 | }, 91 | files: { 92 | src: [ 'package.json', 'readme.txt', 'plugin.php', 'releases/<%= pkg.name %>-<%= pkg.version %>.zip' ] 93 | } 94 | } 95 | }, 96 | gitpush: { 97 | push: { 98 | options: { 99 | tags: true, 100 | remote: 'origin', 101 | branch: 'master' 102 | } 103 | } 104 | }, 105 | replace: { 106 | core_file: { 107 | src: [ 'plugin.php' ], 108 | overwrite: true, 109 | replacements: [{ 110 | from: /Version:\s*(.*)/, 111 | to: "Version: <%= pkg.version %>" 112 | }, { 113 | from: /define\(\s*'CF_FORM_CON_VER',\s*'(.*)'\s*\);/, 114 | to: "define( 'CF_FORM_CON_VER', '<%= pkg.version %>' );" 115 | }] 116 | } 117 | } 118 | 119 | }); 120 | 121 | //load modules 122 | grunt.loadNpmTasks( 'grunt-contrib-compress' ); 123 | grunt.loadNpmTasks( 'grunt-contrib-clean' ); 124 | grunt.loadNpmTasks( 'grunt-contrib-copy' ); 125 | grunt.loadNpmTasks( 'grunt-git' ); 126 | grunt.loadNpmTasks( 'grunt-text-replace' ); 127 | grunt.loadNpmTasks( 'grunt-shell'); 128 | 129 | 130 | //register default task 131 | 132 | //release tasks 133 | grunt.registerTask( 'version_number', [ 'replace:core_file' ] ); 134 | grunt.registerTask( 'pre_vcs', [ 'shell:composer', 'shell:gulp', 'version_number', 'copy', 'compress' ] ); 135 | grunt.registerTask( 'do_git', [ 'gitadd', 'gitcommit', 'gittag', 'gitpush' ] ); 136 | grunt.registerTask( 'just_build', [ 'copy', 'compress' ] ); 137 | 138 | grunt.registerTask( 'release', [ 'pre_vcs', 'do_git', 'clean:post_build' ] ); 139 | 140 | 141 | }; 142 | -------------------------------------------------------------------------------- /Gulpfile.js: -------------------------------------------------------------------------------- 1 | var gulp = require('gulp'); 2 | var concat = require('gulp-concat'); 3 | var watch = require('gulp-watch'); 4 | var minify = require( 'gulp-minify' ); 5 | 6 | gulp.task('js', function() { 7 | gulp.src([ 8 | 'assets/js/cf-connected-ajax.js', 9 | 'assets/js/connector-ui.js' 10 | ]) 11 | .pipe(minify({ 12 | ext:'.min.js', 13 | noSource: true, 14 | mangle: true, 15 | compress: true 16 | })) 17 | .pipe(gulp.dest('assets/js')) 18 | }); 19 | 20 | gulp.task('watch', function(){ 21 | gulp.watch('assets/js/*.js', ['js']); 22 | }); 23 | 24 | gulp.task('default', ['js']); -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Caldera Connected Forms 4 | Create sequences of forms with conditional logic. Split your forms into smaller pieces, with total control over what comes next. Use to combine multiple forms into one, create complex and variable registration and sales paths, surveys, quizzes and more. Take control of a complex process with the simple user interface you've come to expect from Caldera Forms. 5 | 6 | Requires Caldera Forms 1.5 or later. 7 | 8 | For more information on how to use this plugin see: [https://calderawp.com/doc/using-connected-caldera-forms/](https://calderawp.com/doc/using-connected-caldera-forms/) 9 | 10 | ### PUBLIC REPO FOR A PAID PRODUCT 11 | We are experimenting with using public git repos for commercial products. Support will only be provided via our [support system](https://calderawp.com/support/) which requires a valid license. If you are using this plugin please choose to purchase a license to receive support, support our work and 12 | enable live updates. 13 | 14 | Don't use the download link, it's not going to give you a proper build. 15 | 16 | [Feel free to report bug here](https://github.com/CalderaWP/cf-connected-forms/issues) -- pull requests are accepted. 17 | 18 | 19 | ### License & Copyright 20 | * Copyright 2015 David Cramer & Josh Pollock for CalderaWP LLC. 21 | -------------------------------------------------------------------------------- /assets/css/connector-ui.css: -------------------------------------------------------------------------------- 1 | .flowchart-form .window { 2 | background-color: #fff; 3 | border: 1px solid #cfcfcf; 4 | color: #333; 5 | cursor: move; 6 | opacity: 0.6; 7 | padding: 10px 34px 10px 12px; 8 | position: absolute; 9 | text-align: center; 10 | transition: box-shadow 0.15s ease-in 0s; 11 | width: auto; 12 | z-index: 20; 13 | white-space: nowrap; 14 | box-shadow: -9px 0 0 #efefef inset; 15 | } 16 | .flowchart-form .window:hover { 17 | box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); 18 | opacity: 1; 19 | } 20 | .flowchart-form .active { 21 | border: 1px dotted green; 22 | } 23 | 24 | .flowchart-form .hover { 25 | border: 1px dotted red; 26 | } 27 | 28 | .flowchart-form ._jsPlumb_connector { 29 | z-index: 4; 30 | } 31 | 32 | .flowchart-form ._jsPlumb_endpoint, .endpointTargetLabel, .endpointSourceLabel { 33 | z-index: 21; 34 | cursor: pointer; 35 | font-size: 10px; 36 | } 37 | 38 | .endpointSourceLabel:hover{ 39 | opacity: 0.5; 40 | } 41 | .endpointSourceLabel:hover{ 42 | opacity: 1; 43 | } 44 | .flowchart-form .aLabel { 45 | display: none; 46 | padding: 0.4em; 47 | font: 12px sans-serif; 48 | color: #444; 49 | z-index: 21; 50 | opacity: 0.8; 51 | filter: alpha(opacity=80); 52 | cursor: pointer; 53 | } 54 | 55 | .flowchart-form .aLabel._jsPlumb_hover { 56 | background-color: #fff; 57 | color: #333; 58 | border: 1px solid #cfcfcf; 59 | display: inline-block; 60 | } 61 | 62 | .form-node.start-point:hover, 63 | .form-node.start-point{ 64 | box-shadow: 9px 0 0 #a3be5f inset,-9px 0 0 #efefef inset; 65 | cursor: default; 66 | padding: 10px 34px 10px 21px; 67 | } 68 | .delete-endpoint{ 69 | float: left; 70 | } 71 | path, ._jsPlumb_endpoint { 72 | cursor: pointer; 73 | } 74 | 75 | .cf-form-canvas { 76 | position: relative; 77 | } 78 | 79 | #cf-forms-main .cf-node .button { 80 | border-radius: 0; 81 | height: 21px; 82 | padding: 0; 83 | position: absolute; 84 | right: 6px; 85 | } 86 | #cf-forms-main .cf-node .button.add-condition { 87 | top: -1px; 88 | } 89 | #cf-forms-main .cf-node .button.remove-node { 90 | bottom: -1px; 91 | } -------------------------------------------------------------------------------- /assets/js/cf-connected-ajax.js: -------------------------------------------------------------------------------- 1 | var cf_connected_ajax_handler; 2 | 3 | jQuery( function( $ ){ 4 | 5 | $( document ).on( 'click', '.cffld_backnav_btn', function(){ 6 | var $clicked = $(this), 7 | $form = $clicked.closest('.caldera_forms_form'); 8 | 9 | //remove required 10 | $form.find('[required]').removeAttr('required'); 11 | 12 | //set the back nav field to true 13 | $('#' + $clicked.data('field') + '_input' ).val(1); 14 | 15 | 16 | //submit 17 | $form.submit(); 18 | } ); 19 | 20 | cf_connected_ajax_handler = function( obj ){ 21 | $( document ).trigger( 'cf.connected', obj ); 22 | var $target = $( '#' + obj.target ), 23 | inst_id = $( obj.form ).find('form.caldera_forms_form').prop('id'); 24 | $target.replaceWith( obj.form ); 25 | var $newForm = $( document.getElementById( inst_id ) ); 26 | 27 | //scroll to top and focus first field 28 | if ( $newForm.length) { 29 | $('html, body').animate({ 30 | scrollTop: $newForm.offset().top - 200 31 | }, 750, function () { 32 | $newForm.find('input:visible:enabled:first').focus(); 33 | }); 34 | } 35 | 36 | if( obj.hasOwnProperty( 'field_config' ) ){ 37 | $( obj.footer_append ).appendTo( 'body' ); 38 | 39 | //reinit state 40 | var state = new CFState( obj.form_instance, $ ); 41 | state.init( obj.field_config.fields.defaults, obj.field_config.fields.calcDefaults ); 42 | window.cfstate[ obj.form_id ] = state; 43 | 44 | //reinit field config 45 | config_object = new Caldera_Forms_Field_Config( obj.field_config.configs, $(document.getElementById( obj.form_id ) ), $, state ); 46 | config_object.init(); 47 | 48 | //check for star fields and reinit them 49 | if( obj.field_config.fields.hasOwnProperty( 'inputs' ) && obj.field_config.fields.inputs.length ){ 50 | $.each( obj.field_config.fields.inputs, function( i, field ){ 51 | if( 'star_rating' === field.type ){ 52 | var func = field.id + '_stars'; 53 | window[func].apply(null, [] ); 54 | } 55 | }) 56 | } 57 | } 58 | 59 | if( typeof caldera_conditionals === "undefined" || typeof caldera_conditionals[inst_id] === "undefined"){ 60 | return; 61 | } 62 | if( typeof calders_forms_init_conditions === 'function'){ 63 | calders_forms_init_conditions(); 64 | } 65 | 66 | 67 | } 68 | }); 69 | -------------------------------------------------------------------------------- /assets/js/connector-ui.js: -------------------------------------------------------------------------------- 1 | var add_newNode, deleteEndpoint, redraw_all; 2 | 3 | function init_jsPlumb(){ 4 | jsPlumb.ready(function () { 5 | 6 | var instance = jsPlumb.getInstance({ 7 | // default drag options 8 | DragOptions: { cursor: 'move', zIndex: 2000 }, 9 | PaintStyle : { 10 | lineWidth: 2, 11 | strokeStyle: "#a3be5f", 12 | joinstyle: "round", 13 | outlineColor: "#F1F1F1", 14 | outlineWidth: 1 15 | }, 16 | // the overlays to decorate each connection with. note that the label overlay uses a function to generate the label text; in this 17 | // case it returns the 'labelText' member that we set on each connection in the 'init' method below. 18 | ConnectionOverlays: [ 19 | [ "Arrow", { location: 1, width: 10, length : 8 } ], 20 | [ "Label", { 21 | location: [0.5], 22 | id: "label", 23 | cssClass: "aLabel" 24 | }] 25 | ], 26 | Container: "canvas" 27 | }); 28 | 29 | deleteEndpoint = function( obj ){ 30 | instance.deleteEndpoint( obj.trigger.data('endpoint') ); 31 | remove_node( obj.trigger.data('id') ); 32 | //remove_node 33 | } 34 | add_newNode = function( obj ) { 35 | 36 | var d = document.createElement("div"); 37 | var id = jsPlumbUtil.uuid(); 38 | d.className = "window cf-node form-node"; 39 | d.id = id; 40 | d.dataset.form = obj.trigger.data('form'); 41 | d.innerHTML = "" + obj.trigger.data('name') + " "; 42 | d.style.left = "0px"; 43 | d.style.top = "0px"; 44 | instance.getContainer().appendChild(d); 45 | if( jQuery('.start-point').length ){ 46 | d.style.left = "130px"; 47 | d.style.top = "-50px"; 48 | instance.addEndpoint(d, targetEndpoint, { anchor: 'Continuous' }); 49 | }else{ 50 | d.className = "window cf-node form-node start-point"; 51 | d.innerHTML += ""; 52 | } 53 | instance.repaintEverything(); 54 | instance.draggable(d); 55 | 56 | }; 57 | 58 | removeNode = function( el ){ 59 | //console.log( instance ); 60 | var endpoints = instance.getEndpoints( el ), 61 | ep_id = []; 62 | if( endpoints ){ 63 | for( var ep = 0; ep < endpoints.length; ep++ ){ 64 | ep_id.push( endpoints[ ep ].id ); 65 | instance.deleteEndpoint( endpoints[ ep ] ); 66 | } 67 | } 68 | instance.remove( el ); 69 | 70 | return ep_id; 71 | } 72 | redraw_all = function(){ 73 | instance.repaintEverything(); 74 | } 75 | // this is the paint style for the connecting lines.. 76 | var connectorPaintStyle = { 77 | lineWidth: 2, 78 | strokeStyle: "#a3be5f", 79 | joinstyle: "round", 80 | outlineColor: "#F1F1F1", 81 | outlineWidth: 1 82 | }, 83 | // .. and this is the hover style. 84 | connectorHoverStyle = { 85 | lineWidth: 2 , 86 | strokeStyle: "#738e2f", 87 | outlineWidth: 1, 88 | outlineColor: "#F1F1F1" 89 | }, 90 | endpointHoverStyle = { 91 | fillStyle: "#738e2f", 92 | strokeStyle: "#738e2f" 93 | }, 94 | // the definition of source endpoints (the small blue ones) 95 | sourceEndpoint = { 96 | endpoint: "Dot", 97 | paintStyle: { 98 | strokeStyle: "#a3be5f", 99 | fillStyle: "#ffffff", 100 | radius: 6, 101 | lineWidth: 2 102 | }, 103 | isSource: true, 104 | connector: [ "Flowchart", { stub: [20, 20], gap: 10, cornerRadius: 2, alwaysRespectStubs: false } ], 105 | maxConnections: 1, 106 | connectorHoverStyle: connectorHoverStyle, 107 | dragOptions: {}, 108 | overlays: [ 109 | [ "Label", { 110 | label : "", 111 | location: [0.5, 1.5], 112 | cssClass: "endpointSourceLabel" 113 | } ] 114 | ] 115 | }, 116 | // the definition of target endpoints (will appear when the user drags a connection) 117 | targetEndpoint = { 118 | endpoint: "Dot", 119 | paintStyle: { 120 | strokeStyle: "#a3be5f", 121 | fillStyle: "#a3be5f", 122 | radius: 6, 123 | lineWidth: 2 124 | }, 125 | hoverPaintStyle: endpointHoverStyle, 126 | maxConnections: -1, 127 | dropOptions: { hoverClass: "hover", activeClass: "active" }, 128 | isTarget: true, 129 | overlays: [ 130 | //[ "Label", { location: [0.5, -0.5], cssClass: "endpointTargetLabel" } ] 131 | ] 132 | }, 133 | init = function (connection) { 134 | //connection.getOverlay("label").setLabel( connection.sourceId.substring(15) + "-" + connection.targetId.substring(15) ); 135 | }; 136 | 137 | setConnectionLable = function( data, obj ){ 138 | //console.log( obj.trigger.data('endpoint') ); 139 | //console.log( obj.parent ); 140 | //console.log( instance ); 141 | var endpoint = instance.getEndpoint( obj.trigger.data('endpoint') ); 142 | if( endpoint && endpoint.connections.length ){ 143 | endpoint.connections[0].getOverlay("label").setLabel( data.name ); 144 | } 145 | } 146 | var triggerEndpointEdit = function( endpoint, id ){ 147 | var trigger = jQuery('', { 148 | 'data-modal' : 'addEndpoint', 149 | 'data-modal-title' : 'Add Condition Point', 150 | 'data-template' : '#conditions-tmpl', 151 | 'data-request' : 'edit_node', 152 | 'data-modal-width' : '580', 153 | 'data-modal-height' : '420', 154 | 'data-callback' : 'baldrickTriggers', 155 | 'data-id' : endpoint.id, 156 | 'data-form' : jQuery(this).data('form'), 157 | 'data-modal-buttons' : "Close|" + JSON.stringify( { 158 | 'data-modal-autoclose' : 'addEndpoint', 159 | 'data-request' : 'cf_set_endpoint', 160 | 'data-endpoint' : id, 161 | 'data-id' : jQuery(this).data('parent'), 162 | 'class' : 'button-primary ajax-trigger' 163 | } ) + ";Delete|" + JSON.stringify( { 164 | 'data-modal-autoclose' : 'addEndpoint', 165 | 'data-endpoint' : id, 166 | 'data-request' : 'deleteEndpoint', 167 | 'data-id' : endpoint.id, 168 | 'class' : 'button ajax-trigger' 169 | } ) + "|button delete-endpoint" 170 | 171 | }).baldrick().trigger('click'); 172 | } 173 | addPointHome = function( el, id, wait ){ 174 | 175 | var endpoint = instance.addEndpoint( el, sourceEndpoint, { anchor: 'Continuous', uuid : id }); 176 | 177 | endpoint.bind("click", function( endpoint ){ 178 | triggerEndpointEdit( endpoint, id ) 179 | } ); 180 | 181 | if( ! wait ){ 182 | instance.repaintEverything(); 183 | } 184 | 185 | return endpoint; 186 | } 187 | var addTarget = function( to, uuid ){ 188 | instance.addEndpoint( to, targetEndpoint, { anchor: 'Continuous', uuid : uuid }); 189 | } 190 | 191 | var initial_nodes = jsPlumb.getSelector(".cf-form-canvas .form-node"); 192 | // suspend drawing and initialise. 193 | instance.batch(function () { 194 | 195 | // listen for new connections; initialise them the same way we initialise the connections at startup. 196 | instance.bind("connection", function (connInfo, originalEvent) { 197 | //init(connInfo.connection); 198 | var data = cf_get_base_form(), 199 | db = jQuery('#cf-conditions-db'), 200 | condition = data.conditions[ connInfo.sourceEndpoint.id ]; 201 | 202 | data.conditions[ connInfo.sourceEndpoint.id ].connect = connInfo.target.id; 203 | db.val( JSON.stringify( data ) ); 204 | connInfo.connection.getOverlay("label").setLabel( condition.name ); 205 | }); 206 | 207 | instance.bind('click', function( connection ){ 208 | 209 | if( connection.endpoints && connection.endpoints.length ){ 210 | //connection.endpoints[0].trigger('click'); 211 | connection.endpoints[0].fire('click', connection.endpoints[0] ); 212 | } 213 | }); 214 | 215 | instance.draggable( initial_nodes, { grid: [20, 20] }); 216 | // do connections 217 | var initial_connections = jsPlumb.getSelector(".condition-point"); 218 | if( initial_connections.length ){ 219 | var db = jQuery('#cf-conditions-db'), 220 | data = JSON.parse( db.val() ), 221 | endpoints = {}, 222 | new_db = { 223 | _open_condition : '', 224 | conditions : {}, 225 | forms : data.forms 226 | }; 227 | instance.setSuspendDrawing(true); 228 | for( var n = 0; n < initial_connections.length; n++ ){ 229 | 230 | if( ! initial_connections[n].dataset.src || ! initial_connections[n].dataset.to ){ 231 | continue; 232 | } 233 | 234 | var from = 'start' + Math.round(Math.random() * 99866) + Math.round(Math.random() * 99866); 235 | 236 | if( ! endpoints[ initial_connections[n].dataset.to ] ){ 237 | var to = 'end' + Math.round(Math.random() * 99866) + Math.round(Math.random() * 99866); 238 | addTarget( initial_connections[n].dataset.to, to ); 239 | endpoints[ initial_connections[n].dataset.to ] = to; 240 | } 241 | 242 | var endpoint = addPointHome( initial_connections[n].dataset.from, from, true ); 243 | data.conditions[ initial_connections[n].dataset.src ].id = endpoint.id; 244 | new_db.conditions[ endpoint.id ] = data.conditions[ initial_connections[n].dataset.src ]; 245 | instance.connect({uuids: [ from, endpoints[ initial_connections[n].dataset.to ] ], editable: true}).getOverlay("label").setLabel( initial_connections[n].dataset.name ); 246 | 247 | } 248 | 249 | db.val( JSON.stringify( new_db ) ); 250 | instance.setSuspendDrawing(false, true); 251 | instance.repaintEverything(); 252 | instance.recalculateOffsets(); 253 | } 254 | 255 | 256 | 257 | }); 258 | 259 | jsPlumb.fire("jsPlumbFormsLoaded", instance); 260 | 261 | }); 262 | }; -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "calderawp/cf-connected-forms", 3 | "description": "Connect multiple Caldera Forms into a sequence of form", 4 | "type": "wordpress-plugin", 5 | "license": "gplv2+", 6 | "authors": [ 7 | { 8 | "name": "David Cramer", 9 | "email": "David@CalderaWP.com" 10 | }, 11 | { 12 | "name": "Josh Pollock", 13 | "email": "Josh@CalderaWP.com" 14 | } 15 | ], 16 | "minimum-stability": "dev", 17 | "require": { 18 | "calderawp/dismissible-notice": "dev-master", 19 | "calderawp/licensing-helper" : "dev-master" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /composer.lock: -------------------------------------------------------------------------------- 1 | { 2 | "_readme": [ 3 | "This file locks the dependencies of your project to a known state", 4 | "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", 5 | "This file is @generated automatically" 6 | ], 7 | "content-hash": "721f06675ea6ca94a80d97c0ab9cabb1", 8 | "packages": [ 9 | { 10 | "name": "calderawp/dismissible-notice", 11 | "version": "dev-master", 12 | "source": { 13 | "type": "git", 14 | "url": "https://github.com/CalderaWP/dismissible_notice.git", 15 | "reference": "26a0a00cced207464eb005d2eeb3ab93727363d3" 16 | }, 17 | "dist": { 18 | "type": "zip", 19 | "url": "https://api.github.com/repos/CalderaWP/dismissible_notice/zipball/26a0a00cced207464eb005d2eeb3ab93727363d3", 20 | "reference": "26a0a00cced207464eb005d2eeb3ab93727363d3", 21 | "shasum": "" 22 | }, 23 | "type": "library", 24 | "notification-url": "https://packagist.org/downloads/", 25 | "license": [ 26 | "GPL v2+" 27 | ], 28 | "authors": [ 29 | { 30 | "name": "Josh Pollock", 31 | "email": "Josh@JoshPress.net" 32 | } 33 | ], 34 | "description": "Creates a dismissible--via AJAX--admin nag.", 35 | "time": "2015-08-24T20:27:16+00:00" 36 | }, 37 | { 38 | "name": "calderawp/licensing-helper", 39 | "version": "dev-master", 40 | "source": { 41 | "type": "git", 42 | "url": "https://github.com/CalderaWP/licensing-helper.git", 43 | "reference": "05b677379c11bb7417944b68e0aa1cbe7c3cc8e6" 44 | }, 45 | "dist": { 46 | "type": "zip", 47 | "url": "https://api.github.com/repos/CalderaWP/licensing-helper/zipball/05b677379c11bb7417944b68e0aa1cbe7c3cc8e6", 48 | "reference": "05b677379c11bb7417944b68e0aa1cbe7c3cc8e6", 49 | "shasum": "" 50 | }, 51 | "require": { 52 | "calderawp/dismissible-notice": "dev-master", 53 | "php": ">=5.3.0" 54 | }, 55 | "type": "library", 56 | "autoload": { 57 | "psr-4": { 58 | "calderawp\\licensing_helper\\": "src" 59 | } 60 | }, 61 | "notification-url": "https://packagist.org/downloads/", 62 | "license": [ 63 | "GPL-2.0+" 64 | ], 65 | "authors": [ 66 | { 67 | "name": "David Cramer", 68 | "homepage": "http://cramer.co.za", 69 | "role": "Developer" 70 | }, 71 | { 72 | "name": "Josh Pollock", 73 | "email": "Josh@JoshPress.net", 74 | "homepage": "http://joshpress.net" 75 | } 76 | ], 77 | "description": "Helper class for CalderaWP Licensing Manager", 78 | "keywords": [ 79 | "wordpress" 80 | ], 81 | "time": "2017-09-17T19:52:14+00:00" 82 | } 83 | ], 84 | "packages-dev": [], 85 | "aliases": [], 86 | "minimum-stability": "dev", 87 | "stability-flags": { 88 | "calderawp/dismissible-notice": 20, 89 | "calderawp/licensing-helper": 20 90 | }, 91 | "prefer-stable": false, 92 | "prefer-lowest": false, 93 | "platform": [], 94 | "platform-dev": [] 95 | } 96 | -------------------------------------------------------------------------------- /how-to-grunt.md: -------------------------------------------------------------------------------- 1 | * Install Node, NPM, and grunt-cli globally if not already installed. 2 | * https://github.com/joyent/node/wiki/installing-node.js-via-package-manager 3 | * Install grunt-init globally if not already installed. 4 | * `npm install -g grunt-init` 5 | * Install composer to usr/local/bin/composer if not already installed 6 | * Switch to this dir 7 | * Install node modules 8 | * `npm install` 9 | * To make a new release (update version, tag, create zip, push all those changes to git origin) 10 | * Set a new version number in package.json 11 | * `grunt release` 12 | * To just make a new zip, but not release it. 13 | * `grunt just_build` 14 | -------------------------------------------------------------------------------- /includes/calcdefaults.php: -------------------------------------------------------------------------------- 1 | $opt ) { 43 | foreach ( 44 | array( 45 | 'default', 46 | 'label', 47 | 'value', 48 | 'calc_value', 49 | 'calc_default' 50 | ) as $key 51 | ) { 52 | if ( isset( $opt[ $key ] ) && self::is_prev_magic( $opt[ $key ] ) ) { 53 | $field[ 'config' ][ 'option' ][ $opt_id ][ $key ] = Caldera_Forms::do_magic_tags( $field[ 'config' ][ 'option' ][ $opt_id ][ $key ] ); 54 | 55 | } 56 | } 57 | } 58 | 59 | } 60 | 61 | //filter .config options 62 | foreach ( 63 | array( 64 | 'default', 65 | 'value', 66 | ) as $key 67 | ) { 68 | if ( isset( $field[ 'config' ][ $key ] ) && self::is_prev_magic( $field[ 'config' ][ $key ] ) ) { 69 | $field[ 'config' ][ $key ] = Caldera_Forms::do_magic_tags( $field[ 'config' ][ $key ] ); 70 | 71 | } 72 | } 73 | 74 | 75 | 76 | return $field; 77 | } 78 | 79 | /** 80 | * Check if a value is a '{prev:}' magic tag 81 | * 82 | * @since 1.2.2 83 | * 84 | * @param string $test 85 | * 86 | * @return bool 87 | */ 88 | protected static function is_prev_magic( $test ){ 89 | return 0 === strpos( $test, '{prev:' ); 90 | } 91 | 92 | } 93 | -------------------------------------------------------------------------------- /includes/functions.php: -------------------------------------------------------------------------------- 1 | 7 | * @license GPL-2.0+ 8 | * @link 9 | * @copyright 2015 David Cramer & Josh Pollock for CalderaWP 10 | */ 11 | 12 | /** 13 | * Add our hooks 14 | */ 15 | //Most hooks, if added will break advanced file fields submission, so don't use on those 16 | //SEE: https://github.com/CalderaWP/cf-connected-forms/issues/23 17 | if ( empty( $_POST[ 'control' ] ) ) { 18 | add_filter( 'caldera_forms_render_entry_id', 'cf_form_connector_get_stage_state', 10, 2 ); 19 | add_action( 'init', 'cf_form_connector_init_current_position' ); 20 | add_filter( 'caldera_forms_get_form', 'cf_form_connector_setup_processors_check' ); 21 | add_filter( 'caldera_forms_submit_get_form', 'cf_form_connector_setup_processors' ); 22 | add_filter( 'caldera_forms_ajax_return', 'cf_form_connector_control_form_load', 10, 3 ); 23 | add_action( 'caldera_forms_redirect', 'cf_form_connector_control_form_load_manual', 25, 3 ); 24 | add_action( 'admin_init', 'cf_connected_form_init_license' ); 25 | add_action( 'init', 'cf_form_connector_export_merge' ); 26 | add_filter( 'caldera_forms_pre_do_bracket_magic', 'cf_form_connector_prev_magic_tag', 25, 5 ); 27 | add_action( 'cf_form_connector_sequence_started', array( 'CF_Con_Form_Partial', 'status_hook' ), 8, 2 ); 28 | add_action( 'cf_form_connector_sequence_advanced', array( 'CF_Con_Form_Partial', 'add_values_to_main_entry' ), 8, 4 ); 29 | add_filter( 'caldera_forms_render_get_field', array( 'CF_Con_Form_CalcDefaults', 'filter_field' ), 9 ); 30 | } 31 | 32 | //this one is for advanced file fields 33 | add_filter( 'caldera_forms_get_form', 'cf_conn_form_switch_form_for_file_upload' ); 34 | 35 | //Possibly replace standard response 36 | add_action( 'wp_ajax_get_entry', 'cf_form_connector_view_entry', 2 ); 37 | 38 | /** 39 | * Make sure we update ID in tracking data. 40 | * 41 | * @since 1.1.1 42 | */ 43 | add_action( 'caldera_forms_submit_process_end', function( $form, $referrer, $process_id, $entry_id ){ 44 | if( isset ( $_GET[ 'con_current' ], $_GET[ 'con_base' ] ) ){ 45 | $current = $_GET[ 'con_current' ]; 46 | $base = $_GET[ 'con_base' ]; 47 | if( $current != $form[ 'ID' ] ){ 48 | return; 49 | } 50 | }else{ 51 | return; 52 | } 53 | 54 | 55 | cf_form_connected_write_id_to_progress( $entry_id, $base, $current ); 56 | }, 25, 4 ); 57 | 58 | 59 | add_filter( 'caldera_forms_get_form', 'cf_connected_form_merge_fields_filter', 1 ); 60 | function cf_connected_form_merge_fields_filter( $form ){ 61 | if( ! empty( $form [ 'is_connected_form' ]) ) { 62 | if ( ! empty( $form[ 'node' ] ) ) { 63 | remove_filter( 'caldera_forms_get_form', 'cf_connected_form_merge_fields_filter', 1 ); 64 | 65 | $form[ 'fields' ] = array(); 66 | $form[ 'fields' ] = cf_form_connector_get_all_fields( $form ); 67 | 68 | } 69 | 70 | add_filter( 'caldera_forms_get_form', 'cf_connected_form_merge_fields_filter', 1 ); 71 | 72 | } 73 | return $form; 74 | } 75 | 76 | /** 77 | * Initializes the licensing system 78 | * 79 | * @uses "admin_init" action 80 | * 81 | * @since 0.2.0 82 | */ 83 | function cf_connected_form_init_license(){ 84 | 85 | $plugin = array( 86 | 'name' => 'Connected Caldera Forms', 87 | 'slug' => 'caldera-forms-connector', 88 | 'url' => 'https://calderawp.com/', 89 | 'version' => CF_FORM_CON_VER, 90 | 'key_store' => 'cf_connected_forms', 91 | 'file' => CF_FORM_CON_CORE, 92 | ); 93 | 94 | new \calderawp\licensing_helper\licensing( $plugin ); 95 | 96 | } 97 | 98 | /** 99 | * Set new connected form type as template 100 | * 101 | * @since 0.2.0 102 | */ 103 | add_action( 'caldera_forms_get_form_templates', function( $templates ){ 104 | $templates['cf_connected_form'] = array( 105 | 'name' => __( 'Connected Form', 'cf-connected-forms' ), 106 | 'template' => array( 107 | 'is_connected_form' => true 108 | ) 109 | ); 110 | 111 | return $templates; 112 | }, 12); 113 | 114 | /** 115 | * Setup connected form on create 116 | * 117 | * @since 0.2.0 118 | */ 119 | add_filter( 'caldera_forms_create_form', function( $form ){ 120 | if ( isset( $_POST, $_POST[ 'data' ] ) ) { 121 | parse_str( $_POST[ 'data' ], $newform ); 122 | if ( ! empty( $newform[ 'connected_form_primary' ] ) ) { 123 | $form[ 'is_connected_form' ] = true; 124 | } 125 | } 126 | 127 | return $form; 128 | 129 | } ); 130 | 131 | /** 132 | * Setup form tabs for connected form 133 | * 134 | * @since 0.2.0 135 | */ 136 | add_filter( 'caldera_forms_get_panel_extensions', function( $panels ){ 137 | if( !empty( $_GET['edit'] ) ){ 138 | $form = \Caldera_Forms_Forms::get_form( $_GET['edit'] ); 139 | if( !empty( $form['is_connected_form'] ) ){ 140 | 141 | //setup new panels for this type. 142 | //uneeded panels 143 | unset( $panels['form_layout']['tabs']['pages'] ); 144 | unset( $panels['form_layout']['tabs']['conditions'] ); 145 | unset( $panels['form_layout']['tabs']['processors'] ); 146 | unset( $panels['form_layout']['tabs']['variables'] ); 147 | unset( $panels['form_layout']['tabs']['responsive'] ); 148 | 149 | //add needed 150 | $panels['form_layout']['tabs']['layout']['name'] = __( 'Connections', 'connected-forms' ); 151 | $panels['form_layout']['tabs']['layout']['label'] = __( 'Connected Forms Builder', 'connected-forms' ); 152 | $panels['form_layout']['tabs']['layout']['actions'] = array(); 153 | $panels['form_layout']['tabs']['layout']['side_panel'] = null; 154 | $panels['form_layout']['tabs']['layout']['canvas'] = CF_FORM_CON_PATH . 'includes/templates/connection-builder.php'; 155 | 156 | //$panels['form_layout']['tabs']['layout']['canvas'] = CF_FORM_CON_PATH . 'includes/templates/partial.php'; 157 | $panels['form_layout']['tabs'][ 'partial' ] = array( 158 | 'name' => __( 'Partial Submissions', 'connected-forms' ), 159 | 'label' => __( 'Settings for partial submissions', 'connected_Forms' ), 160 | 'location' => 'lower', 161 | 'actions' => array(), 162 | 'side_panel' => null, 163 | 'canvas' => CF_FORM_CON_PATH . 'includes/templates/partials.php' 164 | ); 165 | 166 | // add scripts 167 | wp_enqueue_script( 'jsplumb', CF_FORM_CON_URL . 'assets/js/jsPlumb-1.7.10-min.js', array(), CF_FORM_CON_VER ); 168 | wp_enqueue_script( 'connector-ui', CF_FORM_CON_URL . 'assets/js/connector-ui.min.js', array('jsplumb'), CF_FORM_CON_VER ); 169 | wp_enqueue_style( 'connector-ui', CF_FORM_CON_URL . 'assets/css/connector-ui.css', array(), CF_FORM_CON_VER ); 170 | 171 | } 172 | } 173 | 174 | return $panels; 175 | 176 | }); 177 | 178 | /** 179 | * Add a magic tag for previous values 180 | * 181 | * @uses "caldera_forms_do_magic_tag" 182 | * @deprecated 1.1.0 183 | * 184 | * @since 1.0.4 185 | */ 186 | function cf_form_connector_magic_tag( $tag ) { 187 | _deprecated_function( __FUNCTION__, '1.1.0' ); 188 | global $form; 189 | 190 | $parts = explode( ':', $tag ); 191 | if( count( $parts ) !== 2 || $parts[0] !== 'prev' ){ 192 | return $tag; 193 | } 194 | $check_field = $parts[1]; 195 | 196 | $position = cf_form_connector_get_current_position(); 197 | 198 | if( empty( $form['ID'] ) || empty( $position[ $form['ID'] ] ) ){ 199 | return $tag; 200 | } 201 | 202 | $place = $position[ $form['ID'] ]; 203 | 204 | if( isset( $place['field_values'][ $check_field ] ) ){ 205 | return $place['field_values'][ $check_field ]; 206 | } 207 | // lookup slug 208 | foreach( $place['fields'] as $field_id => $field ){ 209 | 210 | if( $field['slug'] === $check_field && isset( $place['field_values'][ $field_id ] ) ){ 211 | return $place['field_values'][ $field_id ]; 212 | } 213 | } 214 | 215 | return $tag; 216 | 217 | } 218 | 219 | /** 220 | * Get base form for this connected form if is a connected form. 221 | * 222 | * @since 0.2.0 223 | * 224 | * @param array $form Form config 225 | * 226 | * @return bool 227 | */ 228 | function cf_form_connector_get_base_form( $form ){ 229 | if( ! empty( $form['is_connected_form'] ) ){ 230 | foreach( $form['node'] as $node_id => $form_node ){ 231 | if( !empty( $form_node['base'] ) ){ 232 | // setup the form processor bases 233 | return $form_node['form']; 234 | } 235 | } 236 | } 237 | return false; 238 | } 239 | 240 | /** 241 | * Verify this is the correct form 242 | * 243 | * @since 0.2.0 244 | * 245 | * @param array $form Form config 246 | * @param string $id Form ID 247 | * 248 | * @return bool 249 | */ 250 | function cf_form_connector_verify_id( $form, $id ){ 251 | if( !empty( $form['is_connected_form'] ) ){ 252 | foreach( $form['node'] as $node_id => $form_node ){ 253 | if( ! empty( $form_node['form'] ) && $form_node['form'] == $id ){ 254 | return true; // yup its there 255 | } 256 | 257 | } 258 | 259 | } 260 | 261 | return false; 262 | } 263 | 264 | /** 265 | * Ensure we are at right place in sequence 266 | * 267 | * @uses "init" 268 | * 269 | * @since 0.2.0 270 | */ 271 | function cf_form_connector_init_current_position(){ 272 | if( is_user_logged_in() ){ 273 | if( isset( $_COOKIE['cfcfrm_usr'] ) ){ 274 | $logged_in_tracking = cf_form_connector_get_current_position(); 275 | $process_record = get_option( 'cfcfrm_' . $_COOKIE['cfcfrm_usr'], array() ); 276 | 277 | if( empty( $process_record ) && ! empty( $logged_in_tracking ) ){ 278 | $process_record = $logged_in_tracking; 279 | }else{ 280 | if( ! empty( $logged_in_tracking ) ) { 281 | 282 | /** 283 | * Runs when a user logs in and previously tracked progress is about to be written to user meta, and let's you change if data tracked when this user was last logged in has a higher priority than data collected when not logged in or not. 284 | * 285 | * @since 1.2.2 286 | * 287 | * @param bool $prioritize_logged_out Return false to prioritize logged in data over logged out data 288 | * @param array $process_record Previous progress data collected when user was logged out. May be empty 289 | * @param array $logged_in_tracking Previous progress data collected and saved for this user. May be empty. 290 | */ 291 | $prioritize_logged_out = apply_filters( 'cf_form_connector_prioritize_logged_out', true, $process_record, $logged_in_tracking ); 292 | foreach ( $logged_in_tracking as $form_id => $progress ) { 293 | if ( //logged in has progress for form that logged out didn't, so add it 294 | ! isset( $process_record[ $form_id ] ) 295 | //Logged out and logged out have it, but we are prioritizing logged in, so overwrite logged in with logged out. 296 | || ( isset( $process_record[ $form_id ] ) && ! $prioritize_logged_out ) 297 | ) { 298 | $process_record[ $form_id ] = $progress; 299 | } 300 | 301 | 302 | } 303 | 304 | } 305 | 306 | } 307 | 308 | cf_form_connector_set_current_position( $process_record ); 309 | setcookie('cfcfrm_usr', null, time() - 3600, COOKIEPATH, COOKIE_DOMAIN, is_ssl(), true ); 310 | 311 | } 312 | }else{ 313 | if( !isset( $_COOKIE['cfcfrm_usr'] ) ){ 314 | $usertag = uniqid('cfcfrm'); 315 | $expire = time() + ( 60 * DAY_IN_SECONDS ); 316 | setcookie('cfcfrm_usr', $usertag, $expire, COOKIEPATH, COOKIE_DOMAIN, is_ssl(), true); 317 | } 318 | } 319 | } 320 | 321 | /** 322 | * Detemrine correct place in sequence 323 | * 324 | * @since 0.2.0 325 | * 326 | * @return array|mixed|void 327 | */ 328 | function cf_form_connector_get_current_position(){ 329 | if(is_user_logged_in()){ 330 | $user_id = get_current_user_id(); 331 | $data = get_user_meta( $user_id , CF_FORM_CON_SLUG, true ); 332 | 333 | }else{ 334 | // alternate method 335 | if( !empty( $_COOKIE['cfcfrm_usr'] ) ){ 336 | $user_id = $_COOKIE['cfcfrm_usr']; 337 | $data = get_option( 'cfcfrm_' . $user_id, array() ); 338 | }else{ 339 | $user_id = null; 340 | $data = array(); 341 | } 342 | } 343 | 344 | /** 345 | * Filter position data 346 | * 347 | * @since 1.2.0 348 | * 349 | * @param array $data Position data 350 | * @param int|String|null $user_id WP User ID or cookie identifier or null 351 | */ 352 | $data = apply_filters( 'cf_form_connector_position_data', $data, $user_id ); 353 | 354 | return $data; 355 | } 356 | 357 | /** 358 | * Set current place in the sequence 359 | * 360 | * @since 0.2.0 361 | * 362 | * @param array $data 363 | * 364 | * @return int|string|null User identifier 365 | */ 366 | function cf_form_connector_set_current_position( $data ){ 367 | $user_id = null; 368 | if(is_user_logged_in()){ 369 | $user_id = get_current_user_id(); 370 | if( empty( $data[ 'CF5a04d4c0420c3'] ) ){ 371 | $xx = debug_backtrace(); 372 | $x= 1; 373 | } 374 | update_user_meta( $user_id, CF_FORM_CON_SLUG, $data ); 375 | }else{ 376 | // alternate method 377 | if( !empty( $_COOKIE['cfcfrm_usr'] ) ){ 378 | $user_id = 'cfcfrm_' . $_COOKIE['cfcfrm_usr']; 379 | update_option( $user_id, $data ); 380 | } 381 | } 382 | 383 | return $user_id; 384 | } 385 | 386 | /** 387 | * Get the current state for this stage in process 388 | * 389 | * @since 0.2.0 390 | * 391 | * @uses "caldera_forms_render_entry_id" 392 | * 393 | * @param int $entry_id ID of entry 394 | * @param array $form The form configuration 395 | * 396 | * @return mixed 397 | */ 398 | function cf_form_connector_get_stage_state( $entry_id, $form ){ 399 | 400 | $process_record = cf_form_connector_get_current_position(); 401 | if( !empty( $process_record ) && !empty( $process_record[ $form['ID'] ] ) && !empty( $form['current_form'] ) ){ 402 | 403 | if( !empty( $process_record[ $form['ID'] ][ $form['current_form'] ] ) && !empty( $process_record[ $form['ID'] ][ $form['current_form'] ]['id'] ) ){ 404 | if( is_user_logged_in() ){ 405 | return $process_record[ $form['ID'] ][ $form['current_form'] ]['id']; 406 | 407 | }else{ 408 | // no permission, simulate with prepopulate 409 | $entry = Caldera_Forms::get_entry( $process_record[ $form['ID'] ][ $form['current_form'] ]['id'], $form['current_form'] ); 410 | if( !empty( $entry['data'] ) ){ 411 | foreach( $entry['data'] as $field_id => $values) { 412 | $process_record[ $form['ID'] ][ $form['current_form'] ]['pre_data'][ $field_id ] = $values['value']; 413 | } 414 | cf_form_connector_set_current_position( $process_record ); 415 | } 416 | 417 | add_filter( 'caldera_forms_render_pre_get_entry', 'cf_form_connector_partial_populate_form', 10, 2 ); 418 | } 419 | 420 | } 421 | 422 | } 423 | 424 | return $entry_id; 425 | 426 | } 427 | 428 | /** 429 | * Setup processors on the connected form 430 | * 431 | * @since 0.2.0 432 | * 433 | * @uses "caldera_forms_submit_get_form" 434 | * 435 | * @param array $form The form configuration 436 | * 437 | * @return array|null 438 | */ 439 | function cf_form_connector_setup_processors( $form ){ 440 | 441 | if( empty( $form['is_connected_form'] ) ){ 442 | return $form; 443 | } 444 | 445 | // fetch the connected stage form 446 | $base_form = Caldera_Forms_Forms::get_form( cf_form_connector_get_base_form( $form ) ); 447 | 448 | if( !empty( $_POST['cffld_stage'] ) ){ 449 | $current_form = Caldera_Forms_Sanitize::sanitize( $_POST['cffld_stage'] ); 450 | // check this is part of the flow 451 | if( false === cf_form_connector_verify_id( $form, $current_form ) ){ 452 | // erp.. hmm set the base 453 | $current_form = $base_form['ID']; 454 | } 455 | }else{ 456 | $current_form = $base_form['ID']; 457 | } 458 | $stage = $form; // set the primary ( staging form ) 459 | 460 | // get the process record 461 | $process_record = cf_form_connector_get_current_position(); 462 | 463 | // get this form to be run 464 | $form = Caldera_Forms_Forms::get_form( $current_form ); 465 | // check to see if its a back track 466 | if( !empty( $_POST['cffld_backnav'] ) && !empty( $process_record[ $stage['ID'] ] ) ){ 467 | 468 | if( $current_form === $process_record[ $stage['ID'] ]['current_form'] ){ 469 | // prepare state jump 470 | $previous_form = $process_record[ $stage['ID'] ]['previous_form']; 471 | // create backtrack record 472 | if( !empty( $process_record[ $stage['ID'] ][ $previous_form ]['back'] ) ){ 473 | $previous_back_form = $process_record[ $stage['ID'] ][ $previous_form ]['back']; 474 | $process_record[ $stage['ID'] ][ 'previous_form'] = $previous_back_form; 475 | }else{ 476 | unset( $process_record[ $stage['ID'] ][ 'previous_form'] ); 477 | } 478 | $process_record[ $stage['ID'] ][ 'current_form'] = $previous_form; 479 | // capture this without saving on a back as not to do processing 480 | if(!empty($form['fields'])){ 481 | if( empty( $process_record[ $stage['ID'] ][ $current_form ] ) ){ 482 | $process_record[ $stage['ID'] ][ $current_form ] = array(); 483 | } 484 | foreach($form['fields'] as $field_id=>$field){ 485 | if( !empty( $_POST[ $field_id ] ) ){ 486 | $process_record[ $stage['ID'] ][ $current_form ]['pre_data'][ $field_id ] = $_POST[ $field_id ]; 487 | } 488 | } 489 | } 490 | 491 | cf_form_connector_set_current_position( $process_record ); 492 | 493 | $return_data = cf_form_connector_return_data( $current_form, $stage[ 'ID' ], $process_record[ $stage['ID'] ][ 'entry_id' ], 'back' ); 494 | // check for ajax 495 | wp_send_json( array_merge( array( 496 | 'target' => $stage[ 'ID' ] . '_' . (int) $_POST[ '_cf_frm_ct' ], 497 | 'form' => Caldera_Forms::render_form( $stage ) 498 | ), $return_data ) ); 499 | 500 | 501 | } 502 | 503 | } 504 | 505 | $form['stage_form'] = $stage['ID']; 506 | 507 | 508 | if( empty( $process_record[ $stage['ID'] ] ) ){ 509 | 510 | // first form - make the ID if not an edit; 511 | if( empty( $_POST['_cf_frm_edt'] ) ){ 512 | global $wpdb; 513 | // CREATE ENTRY 514 | $new_entry = array( 515 | 'form_id' => $stage['ID'], 516 | 'user_id' => 0, 517 | 'datestamp' => date_i18n( 'Y-m-d H:i:s', time(), 0), 518 | 'status' => 'pending' 519 | ); 520 | // if user logged in 521 | if(is_user_logged_in()){ 522 | $new_entry['user_id'] = get_current_user_id(); 523 | } 524 | 525 | $entry = new Caldera_Forms_Entry_Entry( (object) $new_entry ); 526 | $e = new Caldera_Forms_Entry( $stage, false, $entry ); 527 | $e->save(); 528 | $entry_id = $e->get_entry_id(); 529 | $process_record = array(); 530 | $process_record[ $stage['ID'] ] = array( 531 | 'entry_id' => $entry_id, 532 | 'fields' => array(), 533 | 'field_values' => array(), 534 | 'completed' => false, 535 | 'current_form' => $form['ID'], 536 | 'first_form' => $form[ 'ID' ], 537 | ); 538 | 539 | $user_id = cf_form_connector_set_current_position( $process_record ); 540 | 541 | /** 542 | * Runs when the first step in a Connected Form is submitted 543 | * 544 | * @since 1.1.0 545 | * 546 | * @param string $connected_form_id ID of connected form 547 | * @param int $entry_id If of entry 548 | * @param int|null|string $user_id User identifier (user ID or cookie ID or null) @since 1.2.0 549 | */ 550 | do_action( 'cf_form_connector_sequence_started', $stage['ID'], $entry_id, $user_id ); 551 | } 552 | } 553 | 554 | // disable mailer 555 | $form['mailer']['enable_mailer'] = false; 556 | $form['mailer']['on_insert'] = false; 557 | // setup each connection condition 558 | $final_form_fields = array(); 559 | foreach( $stage['condition_points']['conditions'] as $condition_point => $condition ){ 560 | // ye, lets only use the conditions for this form 561 | if( $condition['form'] != $form['ID'] ){ 562 | continue; 563 | } 564 | 565 | // check its there 566 | if( empty( $stage['node'][ $condition['connect'] ] ) ){ 567 | continue; 568 | } 569 | 570 | // create a processor IF 571 | $processor_id = 'cfp_' . $stage['ID'] . '_' . $condition_point; 572 | $hasBack = false; 573 | if( !empty( $condition['back'] ) ){ 574 | $hasBack = true; 575 | } 576 | 577 | $next_form_id = $stage['node'][ $condition['connect'] ]['form']; 578 | $_entry_id = null; 579 | if( isset( $process_record[ $next_form_id ], $process_record[ $next_form_id ][ 'id' ] ) ){ 580 | $_entry_id = $process_record[ $next_form_id ][ 'id' ]; 581 | } 582 | $form['processors'][ $processor_id ] = array( 583 | 'ID' => $processor_id, 584 | 'type' => 'form-connector', 585 | 'config' => array( 586 | 'next_form_id' => $next_form_id, 587 | 'back_button' => $hasBack, 588 | 'entry_id' => $_entry_id 589 | ), 590 | 'runtimes' => array( 591 | 'insert' => true 592 | ), 593 | 'conditions' => array( 594 | ) 595 | ); 596 | if( !empty( $condition['group'] ) ){ 597 | $form['processors'][ $processor_id ]['conditions'] = array( 598 | 'type' => 'use', 599 | 'group' => $condition['group'] 600 | ); 601 | } 602 | CF_Con_Form_PTrack::set_config( $form['processors'][ $processor_id ][ 'config' ] ); 603 | $has_condition_points = true; 604 | } 605 | 606 | if( empty( $has_condition_points ) && $process_record[ $stage['ID'] ]['current_form'] == $stage['ID'] ){ 607 | // last in process! 608 | $form = $stage; 609 | $form['stage_form'] = $stage['ID']; 610 | // setup field values 611 | global $processed_data; 612 | $processed_data[$stage['ID']] = $process_record[ $stage['ID'] ]['field_values']; 613 | $form['fields'] = $process_record[ $stage['ID'] ]['fields']; 614 | unset( $process_record[ $stage['ID'] ]['fields'] ); 615 | unset( $process_record[ $stage['ID'] ]['field_values'] ); 616 | unset( $process_record[ $stage['ID'] ]['completed'] ); 617 | unset( $process_record[ $stage['ID'] ]['current_form'] ); 618 | unset( $process_record[ $stage['ID'] ]['previous_form'] ); 619 | unset( $process_record[ $stage['ID'] ]['entry_id'] ); 620 | foreach( $process_record[ $stage['ID'] ] as $form_id => $data ){ 621 | Caldera_Forms::set_submission_meta( 'form', array( $form_id => $data['id'] ), $form, '_connected_form'); 622 | } 623 | 624 | $process_record[ $form['stage_form'] ] = array(); 625 | cf_form_connector_set_current_position( $process_record ); 626 | 627 | } 628 | 629 | return $form; 630 | 631 | } 632 | 633 | /** 634 | * When sequence is completed - save 635 | * 636 | * @since 1.0.8 637 | * 638 | * @param array $connected_form Connected form config 639 | * @param array $data Field data to save 640 | * @param array $fields All field configs for fields to save. 641 | */ 642 | function cf_form_connector_save_final( $connected_form, $data, $fields, $entry_id ){ 643 | $form = $connected_form; 644 | $form ['fields' ] = $fields; 645 | 646 | /** 647 | * Change data to save in Connected Forms entry 648 | * 649 | * Runs when sequence is completed, before data is saved 650 | * 651 | * @since 1.1.0 652 | * 653 | * @param array $data Values for each field in sequence 654 | * @param array $form Form config for connected form 655 | * @param int $entry_id ID of entry 656 | */ 657 | $data = apply_filters( 'cf_form_connector_sequence_complete_pre_save', $data, $form, $entry_id ); 658 | if( is_array( $entry_id ) ){ 659 | if( isset( $entry_id[ '_entry_id' ] ) ){ 660 | $entry_id = $entry_id[ '_entry_id' ]; 661 | }else{ 662 | $entry_id = null; 663 | } 664 | } 665 | if ( ! $entry_id ) { 666 | Caldera_Forms_Save_Final::create_entry( $form, $data ); 667 | }else{ 668 | global $processed_data; 669 | $processed_data[ $form[ 'ID' ] . '_' . $entry_id ] = $data; 670 | $entry = new Caldera_Forms_Entry( $form, $entry_id ); 671 | $entry = cf_form_connector_add_fields_to_entry( $entry, $fields, $data ); 672 | 673 | $entry->save(); 674 | Caldera_Forms_Entry_Update::update_entry_status( 'active', $entry_id ); 675 | 676 | } 677 | 678 | /** 679 | * Runs after a connected forms sequence is completed and saved in database 680 | * 681 | * @since 1.1.0 682 | * 683 | * @param array $form Form config for connected form 684 | * @param array $data Values for each field in sequence 685 | * @param int $entry_id ID of entry 686 | */ 687 | do_action( 'cf_form_connector_sequence_complete', $form, $data, $entry_id ); 688 | } 689 | 690 | /** 691 | * Add fields to entry object 692 | * 693 | * NOTE: Does not actually save data 694 | * 695 | * @since 1.1.0 696 | * 697 | * @param Caldera_Forms_Entry $entry Entry object 698 | * @param array $fields Field configs for fields to save 699 | * @param array $field_data Data for each field, keyed by field ID. 700 | * 701 | * @return Caldera_Forms_Entry 702 | */ 703 | function cf_form_connector_add_fields_to_entry( Caldera_Forms_Entry $entry, array $fields, array $field_data ) { 704 | $entry_id = $entry->get_entry_id(); 705 | foreach ( $field_data as $field_id => $value ) { 706 | if ( ! isset( $fields[ $field_id ] ) ) { 707 | continue; 708 | } 709 | 710 | if( empty( $value ) ){ 711 | continue; 712 | } 713 | 714 | 715 | $field = $fields[ $field_id ]; 716 | if ( Caldera_Forms_Fields::not_support( Caldera_Forms_Field_Util::get_type( $field ), 'entry_list' ) ) { 717 | continue; 718 | } 719 | $slug = $field[ 'slug' ]; 720 | 721 | /** @var Caldera_Forms_Entry_Field $field_obj */ 722 | $field_obj = $entry->get_field( $field_id ); 723 | if( $field_obj ){ 724 | if( $value !== $field_obj->get_value() ) { 725 | $field_obj->set_value( $value ); 726 | } 727 | 728 | }else{ 729 | $_value = array( 730 | 'entry_id' => $entry_id, 731 | 'value' => $value, 732 | 'field_id' => $field_id, 733 | 'slug' => $slug 734 | 735 | ); 736 | 737 | $field_obj = new Caldera_Forms_Entry_Field( (object) $_value ); 738 | 739 | } 740 | 741 | $entry->add_field( $field_obj ); 742 | 743 | 744 | } 745 | 746 | return $entry; 747 | 748 | } 749 | 750 | /** 751 | * Check the processors in connected forms 752 | * 753 | * @since 0.2.0 754 | * 755 | * @uses "caldera_forms_get_form" 756 | * 757 | * @param array $form The form configuration 758 | * 759 | * @return mixed 760 | */ 761 | function cf_form_connector_setup_processors_check( $form ){ 762 | if( is_admin() && !empty( $form['is_connected_form'] ) ){ 763 | // setup processors 764 | $form['processors']['_connected_form'] = array( 765 | 'type' => 'form-connector', 766 | 'runtimes' => array( 767 | 'insert' => true 768 | ), 769 | 'config' => array() 770 | ); 771 | 772 | // setup fields 773 | $form_fields = array(); 774 | if( !empty( $_POST['action'] ) && $_POST['action'] == 'get_entry' && !empty( $_POST['entry'] ) ){ 775 | // get meta 776 | $meta = Caldera_Forms::get_entry_meta( (int) $_POST['entry'] , $form ); 777 | 778 | if( !empty( $meta['form-connector']['data']['_connected_form']['entry']['form']['meta_value'] ) ){ 779 | foreach( (array) $meta['form-connector']['data']['_connected_form']['entry']['form']['meta_value'] as $form_meta ){ 780 | $form_fields = array_merge( $form_fields, $form_meta ); 781 | } 782 | } 783 | } 784 | 785 | if( !empty( $form['condition_points']['forms'] ) ){ 786 | $form['fields'] = array(); 787 | foreach( $form['condition_points']['forms'] as $connected_id => $connected_form ){ 788 | if( !empty( $form_fields[ $connected_id ] ) && !empty( $connected_form['fields'] ) ){ 789 | $form['fields'] = array_merge( $form['fields'], $connected_form['fields'] ); 790 | } 791 | } 792 | 793 | // filter the meta to include the connected meta stuff. 794 | add_filter( 'caldera_forms_get_entry_detail', 'cf_form_connector_setup_processors_meta', 10, 3 ); 795 | } 796 | }elseif( !empty( $form['is_connected_form'] ) ){ 797 | wp_enqueue_script( 'cf-conditionals' ); 798 | } 799 | 800 | return $form; 801 | } 802 | 803 | 804 | /** 805 | * Handle meta in processors of connected forms 806 | * 807 | * @since 0.2.0 808 | * 809 | * @param array $entry Entry data 810 | * @param int $entry_id Entry ID 811 | * @param array $form The form configuration 812 | * 813 | * @return mixed 814 | */ 815 | function cf_form_connector_setup_processors_meta( $entry, $entry_id, $form ){ 816 | 817 | if( !empty( $entry['meta']['form-connector']['data']['_connected_form']['entry']['form']['meta_value'] ) ){ 818 | foreach( (array) $entry['meta']['form-connector']['data']['_connected_form']['entry']['form']['meta_value'] as $form_meta ){ 819 | foreach( $form_meta as $connected_form=>$connected_entry ){ 820 | $meta = Caldera_Forms::get_entry_meta( $connected_entry, Caldera_Forms_Forms::get_form( $connected_form ) ); 821 | if( !empty( $meta ) ){ 822 | foreach ($meta as $meta_key => $meta_data ) { 823 | $entry['meta'][ $meta_key ] = $meta_data; 824 | } 825 | } 826 | } 827 | } 828 | unset( $entry['meta']['form-connector'] ); 829 | } 830 | 831 | return $entry; 832 | } 833 | 834 | 835 | /** 836 | * Load connected forms within sequences 837 | * 838 | * @uses "caldera_forms_redirect" 839 | * 840 | * @param string $type Unused 841 | * @param string $url Unused 842 | * @param array $form The form configuration 843 | */ 844 | function cf_form_connector_control_form_load_manual($type, $url, $form ){ 845 | 846 | if( !empty( $form['stage_form'] ) ){ 847 | $stage_form = Caldera_Forms_Forms::get_form( $form['stage_form'] ); 848 | $process_record = cf_form_connector_get_current_position(); 849 | $form = CF_Con_Form_PTrack::maybe_add_connections( $form ); 850 | if( !empty( $form['form_connection'] ) ){ 851 | 852 | $process_record[ $form['stage_form'] ][ $form['ID'] ] = array( 853 | 'id' => $form['form_connection']['entry_id'] 854 | ); 855 | if( !empty( $process_record[ $form['stage_form'] ][ 'previous_form'] ) ){ 856 | $process_record[ $form['stage_form'] ][ $form['ID'] ]['back'] = $process_record[ $form['stage_form'] ][ 'previous_form']; 857 | } 858 | $process_record[ $form['stage_form'] ][ 'previous_form'] = $form['ID']; 859 | $process_record[ $form['stage_form'] ][ 'current_form'] = $form['form_connection']['next_form_id']; 860 | cf_form_connector_set_current_position( $process_record ); 861 | } 862 | } 863 | } 864 | 865 | /** 866 | * @param $form 867 | * 868 | * @return mixed 869 | */ 870 | function cf_form_connector_maybe_add_connections( $form ) 871 | { 872 | if ( empty( $form[ 'form_connection' ] ) ) { 873 | $_processor = CF_Con_Form_PTrack::get_config(); 874 | if ( ! empty( $_processor ) ) { 875 | $form[ 'form_connection' ] = $_processor[ 'config' ]; 876 | 877 | 878 | } 879 | 880 | } 881 | 882 | return $form; 883 | } 884 | 885 | /** 886 | * Do something to loading of forms 887 | * 888 | * @since 0.2.0 889 | * 890 | * @uses "caldera_forms_ajax_return" 891 | * 892 | * @param string $out 893 | * @param array $form The form configuration 894 | * 895 | * @return mixed 896 | */ 897 | function cf_form_connector_control_form_load( $out, $form ){ 898 | 899 | if( $out['type'] !== 'complete' ){ 900 | return $out; 901 | } 902 | 903 | if( !empty( $form['stage_form'] ) ){ 904 | $stage_form = Caldera_Forms_Forms::get_form( $form[ 'stage_form' ] ); 905 | $process_record = cf_form_connector_get_current_position(); 906 | $fields = array_merge( 907 | isset( $process_record[ $form[ 'stage_form'] ]['fields'] ) ? $process_record[ $form[ 'stage_form' ] ][ 'fields' ] : array(), 908 | isset( $form[ 'fields' ] ) ? $form[ 'fields' ] : array() 909 | ); 910 | $process_record[ $form[ 'stage_form' ] ][ 'fields' ] = $fields; 911 | $field_values = array_merge( 912 | Caldera_Forms::get_submission_data( $form ), 913 | isset( $process_record[ $form[ 'stage_form' ] ][ 'field_values' ] ) ? $process_record[ $form[ 'stage_form'] ][ 'field_values' ] : array() 914 | ); 915 | $process_record[ $form['stage_form'] ][ 'field_values' ] = $field_values; 916 | $form = CF_Con_Form_PTrack::maybe_add_connections( $form ); 917 | if( !empty( $form['form_connection'] ) ){ 918 | 919 | $process_record[ $form['stage_form'] ][ $form['ID'] ] = array( 920 | 'id' => $form['form_connection']['entry_id'] 921 | ); 922 | 923 | if( empty( $form['form_connection']['back_button'] ) ){ 924 | $process_record[ $form['stage_form'] ][ $form['ID'] ]['no_back'] = true; 925 | } 926 | 927 | if( !empty( $process_record[ $form['stage_form'] ][ 'previous_form'] ) ){ 928 | $process_record[ $form['stage_form'] ][ $form['ID'] ]['back'] = $process_record[ $form['stage_form'] ][ 'previous_form']; 929 | } 930 | $process_record[ $form['stage_form'] ][ 'previous_form'] = $form['ID']; 931 | $process_record[ $form['stage_form'] ][ 'current_form'] = $form['form_connection']['next_form_id']; 932 | 933 | 934 | cf_form_connector_set_current_position( $process_record ); 935 | 936 | // handler proper redirects 937 | if( !empty( $out['url'] ) ){ 938 | wp_send_json( $out ); 939 | } 940 | 941 | $connected_form_id = $stage_form[ 'ID' ]; 942 | $entry_id = $process_record[ $connected_form_id ][ 'entry_id' ]; 943 | 944 | /** 945 | * Runs when a form in a Connected Forms sequence, which is not the last form is submitted 946 | * 947 | * @since 1.1.0 948 | * 949 | * @param string $connected_form_id ID of connected form 950 | * @param string $current_form_id The ID of the form in sequence that was just submitted 951 | * @param int $entry_id If of entry 952 | * @param array $sequence_data Data for current sequence 953 | */ 954 | do_action( 'cf_form_connector_sequence_advanced', $connected_form_id, $form[ 'ID' ], $entry_id, $process_record[ $connected_form_id ] ); 955 | $instance_id = isset( $_POST[ '_cf_frm_ct' ] ) ? (int) $_POST[ '_cf_frm_ct' ] : 1; 956 | 957 | $next_form_html = Caldera_Forms::render_form( $stage_form ); 958 | $return_data = cf_form_connector_return_data( $form[ 'ID' ], $connected_form_id, $entry_id ); 959 | $next_form = Caldera_Forms_Forms::get_form( $process_record[ $connected_form_id ][ 'current_form' ] ); 960 | $next_form = CF_Con_Form_CalcDefaults::filter_form( $next_form ); 961 | $js_config = new Caldera_Forms_Field_JS( $next_form, $instance_id ); 962 | 963 | 964 | $footer_append = ''; 965 | if( method_exists( 'Caldera_Forms_Render_Util', 'get_footer_object' ) ){ 966 | $footer_object = Caldera_Forms_Render_Util::get_footer_object( $connected_form_id ); 967 | if( is_object( $footer_object ) ){ 968 | $footer_append = $footer_object->get_data_as_string(); 969 | } 970 | } 971 | 972 | $return_data = array_merge( array( 973 | 'target' => $form[ 'stage_form' ] . '_' . $instance_id, 974 | 'form' => $next_form_html, 975 | 'instance_id' => $instance_id, 976 | 'field_config' => $js_config->to_array(), 977 | 'form_id' => esc_attr( $next_form[ 'ID' ] ), 978 | 'footer_append' => $footer_append, 979 | 'form_instance' => esc_attr( $next_form[ 'ID' ] . '_' . $instance_id ) 980 | ), $return_data ); 981 | wp_send_json( $return_data ); 982 | }else{ 983 | // is current = stage ? yup last form last process. 984 | if( empty( $form['form_connection'] ) 985 | || ( !empty( $process_record[ $form['stage_form'] ][ 'current_form'] ) && $process_record[ $form['stage_form'] ][ 'current_form'] === $form['stage_form'] ) ) 986 | { 987 | 988 | 989 | 990 | $connected_form = Caldera_Forms_Forms::get_form( $form['stage_form'] ); 991 | if( is_array( $connected_form ) && ( ! empty( $connected_form['mailer']['enable_mailer'] ) || $connected_form['mailer']['on_insert'] ) ){ 992 | 993 | $entry_id = $process_record[ $connected_form[ 'ID' ] ][ 'entry_id' ]; 994 | $data = $process_record[ $form['stage_form'] ][ 'field_values' ]; 995 | cf_form_connector_save_final( $connected_form, $data, $process_record[ $connected_form[ 'ID' ] ][ 'fields' ], $entry_id ); 996 | 997 | /** 998 | * Choose to clear saved sequence from tracking data when sequence is complete 999 | * 1000 | * @since 1.3.0 1001 | * 1002 | * @param bool $clear Default is true. 1003 | * @param array $connected_form Connected form's config 1004 | */ 1005 | if ( apply_filters( 'cf_form_connector_clear_after_complete', true, $connected_form ) ) { 1006 | $process_record[ $form['stage_form'] ] = array(); 1007 | } else{ 1008 | $process_record[ $connected_form[ 'ID' ] ][ 'current_form' ] = $process_record[ $connected_form[ 'ID' ] ] [ 'first_form' ]; 1009 | $process_record[ $connected_form[ 'ID' ] ]['completed'] = false; 1010 | } 1011 | 1012 | cf_form_connector_set_current_position($process_record); 1013 | 1014 | 1015 | if ( class_exists( 'Caldera_Forms_Magic_Summary' ) ) { 1016 | $message_setting = $connected_form[ 'mailer' ][ 'email_message' ]; 1017 | if ( false !== strpos( $message_setting, '{summary}' ) ) { 1018 | $magic_parser = new Caldera_Forms_Magic_Summary( $connected_form, $data ); 1019 | if ( ! isset( $connected_form[ 'mailer' ][ 'email_type' ] ) || $connected_form[ 'mailer' ][ 'email_type' ] == 'html' ) { 1020 | $magic_parser->set_html_mode( true ); 1021 | 1022 | } else { 1023 | $magic_parser->set_html_mode( false ); 1024 | } 1025 | 1026 | $magic_parser->set_fields( cf_form_connector_get_all_fields( $connected_form ) ); 1027 | 1028 | $message_setting = str_replace( '{summary}', $magic_parser->get_tag(), $message_setting ); 1029 | $connected_form[ 'mailer' ][ 'email_message' ] = $message_setting; 1030 | } 1031 | } 1032 | 1033 | 1034 | 1035 | Caldera_Forms_Save_Final::do_mailer( $connected_form, $entry_id, $data ); 1036 | } 1037 | return $out; 1038 | } 1039 | 1040 | $process_record[ $form['stage_form'] ][ $form['ID'] ] = array( 1041 | 'id' => (int) Caldera_Forms::do_magic_tags( '{entry_id}' ) 1042 | ); 1043 | if( !empty( $process_record[ $form['stage_form'] ][ 'previous_form'] ) ){ 1044 | $process_record[ $form['stage_form'] ][ $form['ID'] ]['back'] = $process_record[ $form['stage_form'] ][ 'previous_form']; 1045 | } 1046 | $process_record[ $form['stage_form'] ][ 'previous_form'] = $form['ID']; 1047 | $process_record[ $form['stage_form'] ][ 'current_form'] = $form['stage_form']; 1048 | $process_record[ $form['stage_form'] ]['fields'] = array_merge( ( array ) $process_record[ $form['stage_form'] ]['fields'], $form['fields'] ); 1049 | $process_record[ $form['stage_form'] ]['field_values'] = array_merge( ( array ) $process_record[ $form['stage_form'] ]['field_values'], Caldera_Forms::get_submission_data( $form ) ); 1050 | 1051 | cf_form_connector_set_current_position( $process_record ); 1052 | 1053 | Caldera_Forms::process_submission(); 1054 | exit; 1055 | } 1056 | 1057 | } 1058 | 1059 | return $out; 1060 | 1061 | } 1062 | 1063 | /** 1064 | * Prepare filterable parts of AJAX return 1065 | * 1066 | * @since 1.1.1 1067 | * 1068 | * NOTE: Add target and form indexes after this or shit will break. 1069 | * 1070 | * @param string $last_form_id Last form ID 1071 | * @param string $connected_form_id Connected form ID 1072 | * @param int $entry_id Entry ID for connected form 1073 | * @param string $type Optional. Type of return. Default is "advance" 1074 | * @return array 1075 | */ 1076 | function cf_form_connector_return_data( $last_form_id, $connected_form_id, $entry_id, $type = 'advance' ){ 1077 | 1078 | 1079 | $return_data = array( 1080 | 'connected_form_id' => $connected_form_id, 1081 | 'last_form_id' => $last_form_id, 1082 | 'entry_id' => $entry_id, 1083 | 'type' => $type, 1084 | ); 1085 | 1086 | /** 1087 | * Filter data to be sent back to DOM by connected forms 1088 | * 1089 | * Use to customize data for cf.connected JS event. DOES NOT include target and form which intentionally not filterable 1090 | * 1091 | * @since 1.1.1 1092 | * 1093 | * @param array $return_data Data to be sent back to DOM 1094 | * 1095 | */ 1096 | return apply_filters( 'cf_form_connector_return_data', $return_data ); 1097 | } 1098 | 1099 | 1100 | function cf_form_connector_partial_populate_form( $data, $form ){ 1101 | 1102 | if( !empty( $form['current_form'] ) ){ 1103 | $process_record = cf_form_connector_get_current_position(); 1104 | 1105 | if( !empty( $process_record[ $form['ID'] ][ $form['current_form'] ]['pre_data'] ) ){ 1106 | return $process_record[ $form['ID'] ][ $form['current_form'] ]['pre_data']; 1107 | } 1108 | } 1109 | 1110 | return $data; 1111 | } 1112 | 1113 | 1114 | add_filter( 'caldera_forms_render_get_form', function( $form ){ 1115 | if( !empty( $form['is_connected_form'] ) ){ 1116 | $new_form = false; 1117 | 1118 | $base_form = cf_form_connector_get_base_form( $form ); 1119 | 1120 | 1121 | if ( empty( $_POST ) && method_exists( 'Caldera_Forms_Forms', 'get_fields') ) { 1122 | $field_types_in_sequence = array(); 1123 | $field_types = apply_filters( 'caldera_forms_get_field_types', array() ); 1124 | foreach ( $form[ 'node' ] as $node ) { 1125 | $_form = Caldera_Forms_Forms::get_form( $node[ 'form' ] ); 1126 | $fields = Caldera_Forms_Forms::get_fields( $_form ); 1127 | foreach( $fields as $id => $field ){ 1128 | $type = Caldera_Forms_Field_Util::get_type( $field,$_form ); 1129 | if( ! array_key_exists( $type, $field_types_in_sequence ) ){ 1130 | $field_types_in_sequence[ $type ] = $field; 1131 | } 1132 | 1133 | } 1134 | 1135 | } 1136 | 1137 | if( ! empty( $field_types_in_sequence ) ){ 1138 | foreach ( $field_types_in_sequence as $type => $field ) { 1139 | 1140 | Caldera_Forms_Render_Assets::enqueue_field_scripts( $field_types, $field); 1141 | } 1142 | } 1143 | } 1144 | 1145 | // Some checks to see if this user is working on this for / or whatever to load the new entry 1146 | // if nothing i.e a new start, then we're on the base form! 1147 | // get the process record 1148 | $process_record = cf_form_connector_get_current_position(); 1149 | 1150 | if(!empty( $process_record[ $form['ID'] ] ) && false === $process_record[ $form['ID'] ]['completed'] ){ 1151 | if( !empty( $process_record[ $form['ID'] ]['previous_form'] ) ){ 1152 | $previous_form = $process_record[ $form['ID'] ]['previous_form']; 1153 | if( !empty( $process_record[ $form['ID'] ][ $process_record[ $form['ID'] ]['previous_form'] ] ) && !empty( $process_record[ $form['ID'] ][ $process_record[ $form['ID'] ]['previous_form'] ]['no_back'] ) ){ 1154 | $no_back_button = true; 1155 | } 1156 | } 1157 | $new_form = Caldera_Forms_Forms::get_form( $process_record[ $form['ID'] ]['current_form'] ); 1158 | if( ! is_array( $new_form ) || empty( $new_form[ 'ID' ] ) ){ 1159 | reset( $form[ 'node' ] ); 1160 | $new_form_id = ! empty( $form[ 'node' ][ key( $form[ 'node' ] ) ] ) 1161 | //use first index of form[ 'node' ] which should always be there 1162 | ? $form[ 'node' ][ key( $form[ 'node' ] ) ][ 'form' ] 1163 | //use the connected form ID 1164 | : $form[ 'ID' ]; 1165 | 1166 | $new_form = Caldera_Forms::get_form( $new_form_id ); 1167 | } 1168 | 1169 | if( !empty( $process_record[ $form['ID'] ][ $new_form['ID'] ]['pre_data'] ) && empty( $process_record[ $form['ID'] ][ $new_form['ID'] ]['id'] ) ){ 1170 | add_filter( 'caldera_forms_render_pre_get_entry', 'cf_form_connector_partial_populate_form', 10, 2 ); 1171 | } 1172 | } 1173 | 1174 | if( ! is_array( $new_form ) || empty( $new_form[ 'ID' ] ) ){ 1175 | // not form replacement, load up base 1176 | $new_form = Caldera_Forms_Forms::get_form( $base_form ); 1177 | } 1178 | 1179 | // check if there are any connection points 1180 | foreach( $form['condition_points']['conditions'] as $condition_point => $condition ){ 1181 | 1182 | // ye, lets only use the conditions for this form 1183 | if( $condition['form'] != $new_form['ID'] ){ 1184 | continue; 1185 | } 1186 | // check its there 1187 | if( empty( $form['node'][ $condition['connect'] ] ) ){ 1188 | continue; 1189 | } 1190 | // yes theres a connection at least AKA not the last form 1191 | $has_connections = true; 1192 | } 1193 | 1194 | $current_form = $new_form['ID']; 1195 | $new_form['ID'] = $form['ID']; 1196 | $new_form['current_form'] = $current_form; 1197 | 1198 | 1199 | if ( isset( $new_form[ 'layout_grid' ], $new_form[ 'layout_grid' ][ 'structure' ] ) ) { 1200 | $pages = explode( '#', $new_form['layout_grid']['structure'] ); 1201 | }else{ 1202 | $pages = array(); 1203 | } 1204 | 1205 | $submit_button_position = false; 1206 | foreach ( $new_form[ 'fields' ] as $field_id => $field ) { 1207 | // remove any submit buttons 1208 | 1209 | if ( $field[ 'type' ] == 'button' && $field[ 'config' ][ 'type' ] == 'submit' ) { 1210 | $submit_button_position = $new_form[ 'layout_grid' ][ 'fields' ][ $field_id ]; 1211 | unset( $form[ 'fields' ][ $field_id ] ); 1212 | unset( $new_form[ 'layout_grid' ][ 'fields' ][ $field_id ] ); 1213 | } 1214 | 1215 | } 1216 | 1217 | //Remove all submit/back/next buttons 1218 | //No multi-page forms and no seperate submits 1219 | foreach( Caldera_Forms_Forms::get_fields( $new_form, false ) as $field_id => $field ){ 1220 | if( 'button' == Caldera_Forms_Field_Util::get_type( $field, $new_form ) && in_array( $field[ 'config' ][ 'type' ], array( 1221 | 'submit', 1222 | 'back', 1223 | 'next', 1224 | ) ) ){ 1225 | unset( $new_form[ 'fields' ][ $field_id ] ); 1226 | } 1227 | 1228 | } 1229 | 1230 | $rows = explode( '|', $new_form[ 'layout_grid' ][ 'structure' ] ); 1231 | $last_row = count( $rows ) + 1; 1232 | if(count( $pages ) <= 1 ) { 1233 | // single page- add to this one 1234 | $new_form[ 'layout_grid' ][ 'structure' ] .= '|6:6'; 1235 | $submit_button_position = $last_row . ':2'; 1236 | 1237 | } 1238 | if( empty( $submit_button_position ) ){ 1239 | $submit_button_position = $last_row . ':2'; 1240 | 1241 | } 1242 | 1243 | $new_form[ 'layout_grid' ][ 'fields' ][ 'cffld_nextnav' ] = $submit_button_position; 1244 | 1245 | 1246 | 1247 | $new_form[ 'layout_grid' ][ 'fields' ][ 'cffld_stage' ] = $last_row . ':2'; 1248 | 1249 | if( !empty( $previous_form ) && $previous_form != $new_form['ID'] ){ 1250 | 1251 | if( empty( $no_back_button ) ){ 1252 | $new_form['layout_grid']['fields']['cffld_backnav'] = $last_row . ':1'; 1253 | $new_form['fields']['cffld_backnav'] = array( 1254 | 'ID' => 'cffld_backnav', 1255 | 'type' => 'cfcf_back_nav', 1256 | 'label' => __('Back', 'cf-form-connector' ), 1257 | 'slug' => 'cfcf_back_nav', 1258 | 'conditions' => array( 1259 | 'type' => '' 1260 | ), 1261 | 'caption' => '', 1262 | 'config' => array( 1263 | 'custom_class' => 'cf-con-btn cf-con-backnav cf-con-backnav-' . $new_form[ 'ID' ], 1264 | 'visibility' => 'all', 1265 | 'type' => 'back', 1266 | 'class' => 'btn btn-default', 1267 | 'default' => '' 1268 | ) 1269 | ); 1270 | } 1271 | } 1272 | 1273 | $is_submit = ! empty( $has_connections ); 1274 | 1275 | /** 1276 | * Prevent the next (or submit) button to be added to form 1277 | * 1278 | * @since 1.1.2 1279 | * 1280 | * @param bool $use Should next (or submit) button be added to form. 1281 | * @param bool $is_submit Is this a submit button? If false, is next button. 1282 | * @param array $new_form Current form 1283 | * @param string $base_form ID of connected form 1284 | * @param array $process_record Current progress in sequence 1285 | */ 1286 | $add_next = apply_filters( 'cf_form_connector_add_next_btn', true, $is_submit, $new_form, $base_form, $process_record ); 1287 | if ( $add_next ) { 1288 | $new_form[ 'fields' ][ 'cffld_nextnav' ] = array( 1289 | 'ID' => 'cffld_nextnav', 1290 | 'type' => 'cfcf_next_nav', 1291 | 'label' => ($is_submit ? __( 'Next', 'cf-form-connector' ) : __( 'Submit', 'cf-form-connector' ) ), 1292 | 'slug' => 'cfcf_next_nav', 1293 | 'conditions' => array( 1294 | 'type' => '' 1295 | ), 1296 | 'caption' => '', 1297 | 'config' => array( 1298 | 'custom_class' => ( $is_submit ? 'cf-con-btn cf-con-front-nav cf-con-front-nav-' . $new_form[ 'ID' ] : 'cf-con-btn cf-con-submit cf-con-submit-' . $new_form[ 'ID' ] ), 1299 | 'visibility' => 'all', 1300 | 'type' => 'next', 1301 | 'class' => 'btn btn-default pull-right', 1302 | ) 1303 | ); 1304 | } 1305 | 1306 | 1307 | 1308 | $new_form['fields']['cffld_stage'] = array( 1309 | 'ID' => 'cffld_stage', 1310 | 'type' => 'hidden', 1311 | 'label' => '', 1312 | 'slug' => 'cffld_stage', 1313 | 'conditions' => array( 1314 | 'type' => '' 1315 | ), 1316 | 'caption' => '', 1317 | 'config' => array( 1318 | 'custom_class' => '', 1319 | 'visibility' => 'all', 1320 | 'default' => $current_form 1321 | ) 1322 | ); 1323 | 1324 | 1325 | $new_form['connected_stage'] = true; 1326 | // add filter to register the nav buttoms ( this is so that they dont show in form builder ) 1327 | add_filter('caldera_forms_get_field_types', 'cf_form_connector_register_fields'); 1328 | 1329 | 1330 | if( Caldera_Forms_Render_Assets::should_minify() ){ 1331 | $url = CF_FORM_CON_URL . 'assets/js/cf-connected-ajax.min.js'; 1332 | }else{ 1333 | $url = CF_FORM_CON_URL . 'assets/js/cf-connected-ajax.js'; 1334 | } 1335 | // setup the js handler if ajax 1336 | wp_enqueue_script( 'cf-form-connector-ajax', $url, array( 'jquery' ), CF_FORM_CON_VER , true ); 1337 | $new_form['custom_callback'] = 'cf_connected_ajax_handler'; 1338 | 1339 | //always use ajax 1340 | $new_form[ 'form_ajax' ] = 1; 1341 | $form[ 'form_ajax' ] = 1; 1342 | 1343 | return $new_form; 1344 | } 1345 | 1346 | return $form; 1347 | } ); 1348 | 1349 | /** 1350 | * Registers the Form Connector processor 1351 | * 1352 | * @since 0.1.0 1353 | * @param array $processors Array of current registered processors 1354 | * 1355 | * @return array array of regestered processors 1356 | */ 1357 | function cf_form_connector_register($processors){ 1358 | if( is_admin() && !empty( $_GET['edit'] ) ){ 1359 | return $processors; 1360 | } 1361 | 1362 | $processors['form-connector'] = array( 1363 | "name" => __('Connected Forms', 'cf-form-connector'), 1364 | "description" => __( 'Connect multiple forms.', 'cf-form-connector'), 1365 | "author" => "David Cramer & Josh Pollock for CalderaWP LLC", 1366 | "author_url" => "https://CalderaWP.com", 1367 | "post_processor" => 'cf_form_connector_process', 1368 | "template" => CF_FORM_CON_PATH . "includes/config.php", 1369 | 1370 | ); 1371 | 1372 | return $processors; 1373 | 1374 | } 1375 | 1376 | /** 1377 | * Proccesss submission 1378 | * 1379 | * @since 0.1.0 1380 | * 1381 | * @param array $config Processor config 1382 | * @param array $form Form config 1383 | * 1384 | * @return array 1385 | */ 1386 | function cf_form_connector_process( $config, $form ) { 1387 | $form['form_connection'] = $config; 1388 | $form['form_connection']['entry_id'] = Caldera_Forms::get_field_data( '_entry_id', $form ); 1389 | CF_Con_Form_PTrack::set_config($form['form_connection']); 1390 | } 1391 | 1392 | /** 1393 | * Change form to be rendered 1394 | * 1395 | * @since 0.1.0 1396 | * 1397 | * @uses "caldera_forms_render_get_form" filter 1398 | * 1399 | * @param array $form The form config 1400 | * 1401 | * @return array 1402 | */ 1403 | function cf_form_connector_change_form( $form ) { 1404 | if ( 1405 | isset( $_GET[ 'cf_con' ] ) 1406 | && isset( $_GET[ 'cf_con_form_id' ] ) 1407 | && isset( $_GET[ 'cf_con_nonce' ] ) 1408 | && $_GET[ 'cf_con' ] 1409 | && wp_verify_nonce( $_GET[ 'cf_con_nonce' ], 'cf_con_nonce' ) 1410 | ) { 1411 | remove_filter( 'caldera_forms_render_get_form', 'cf_form_connector_change_form' ); 1412 | $_form = Caldera_Forms_Forms::get_form( Caldera_Forms_Sanitize::sanitize( $_GET[ 'cf_con_form_id' ] ) ); 1413 | if ( is_array( $_form ) ) { 1414 | if ( isset( $_GET[ 'cf_id' ] ) && 0 < absint( $_GET[ 'cf_id' ] ) ) { 1415 | add_filter( 'caldera_forms_render_entry_id', function( $entry_id ) { 1416 | return (int) $_GET[ 'cf_id' ]; 1417 | } ); 1418 | } 1419 | $form = $_form; 1420 | } 1421 | } 1422 | 1423 | return $form; 1424 | 1425 | } 1426 | 1427 | 1428 | /** 1429 | * Register the nav fields 1430 | * 1431 | * @since 0.2.0 1432 | * 1433 | * 1434 | * @param array $fieldtypes list of currently registered field types 1435 | * 1436 | * @return array altered list of fieldtypes with password field added. 1437 | */ 1438 | function cf_form_connector_register_fields($fieldtypes){ 1439 | 1440 | $fieldtypes['cfcf_back_nav'] = array( 1441 | "field" => __( "Back Navigation --- Connected Forms", 'cf-form-connector' ), 1442 | "file" => CF_FORM_CON_PATH . "includes/templates/back_field.php", 1443 | "category" => __("Button", "cf-form-connector"), 1444 | "description" => __( 'Move Backwards In A Connected Forms Sequence', 'cf-form-connector' ), 1445 | "setup" => array( 1446 | "not_supported" => array( 1447 | 'entry_list' 1448 | ) 1449 | ) 1450 | ); 1451 | $fieldtypes['cfcf_next_nav'] = array( 1452 | "field" => __( "Forward Navigation --- Connected Forms", 'cf-form-connector' ), 1453 | "file" => CF_FORM_CON_PATH . "includes/templates/next_field.php", 1454 | "category" => __("Button", "cf-form-connector"), 1455 | "description" => __( 'Move Forwards In A Connected Forms Sequence', 'cf-form-connector' ), 1456 | "setup" => array( 1457 | "not_supported" => array( 1458 | 'entry_list' 1459 | ) 1460 | ) 1461 | ); 1462 | 1463 | return $fieldtypes; 1464 | } 1465 | 1466 | /** 1467 | * Merge entries during export 1468 | * 1469 | * @uses init 1470 | * 1471 | * @since 1.0.2 1472 | */ 1473 | function cf_form_connector_export_merge(){ 1474 | if( is_admin() && isset( $_GET['export'], $_GET[ 'page' ] ) && $_GET['export'] && 'caldera-forms' == $_GET[ 'page' ] ){ 1475 | $id = strip_tags( $_GET[ 'export' ] ); 1476 | $form = Caldera_Forms_Forms::get_form( $id ); 1477 | global $cf_con_fields; 1478 | $cf_con_fields = array(); 1479 | if( isset( $form[ 'is_connected_form' ] ) && isset( $form[ 'node' ]) ){ 1480 | $cf_con_fields = cf_from_connector_merge_fields( $form ); 1481 | 1482 | } 1483 | 1484 | add_filter( 'caldera_forms_get_form', function( $form, $id ){ 1485 | if( $_GET[ 'export' ] == $id && !empty( $form['is_connected_form'] ) ){ 1486 | global $cf_con_fields; 1487 | $form[ 'fields' ] = $cf_con_fields; 1488 | } 1489 | 1490 | return $form; 1491 | }, 50, 2 ); 1492 | 1493 | 1494 | } 1495 | 1496 | } 1497 | 1498 | function cf_from_connector_merge_fields( $connected_form ){ 1499 | $merged_fields = array(); 1500 | foreach( array_reverse( $connected_form[ 'node' ] ) as $node ){ 1501 | $_id = $node[ 'form' ]; 1502 | $_form = Caldera_Forms_Forms::get_form( $_id ); 1503 | if( method_exists( 'Caldera_Forms_Forms', 'get_fields')){ 1504 | $_fields = Caldera_Forms_Forms::get_fields( $_form, false ); 1505 | }else{ 1506 | $_fields = $_form[ 'fields' ]; 1507 | } 1508 | 1509 | if( empty( $merged_fields ) ){ 1510 | $merged_fields = $_fields; 1511 | }else{ 1512 | $merged_fields = array_merge( $merged_fields, $_fields ); 1513 | } 1514 | } 1515 | 1516 | return $merged_fields; 1517 | } 1518 | 1519 | /** 1520 | * Validate form config 1521 | * 1522 | * This should probably go in CF itself 1523 | * 1524 | * @since 1.0.5 1525 | */ 1526 | add_filter( 'caldera_forms_get_form', function( $form ){ 1527 | if( ! isset( $form[ 'is_connected_form' ] ) ){ 1528 | $form[ 'is_connected_form' ] = false; 1529 | } 1530 | 1531 | foreach( array( 'processors','layout_grid', 'fields', 'mailer' ) as $key ){ 1532 | if( ! isset( $form[ $key ] ) ){ 1533 | $form[ $key ] = array(); 1534 | } 1535 | } 1536 | 1537 | return $form; 1538 | }); 1539 | 1540 | /** 1541 | * Add query args to submit url to identify as connected forms and what forms are involvesd 1542 | * 1543 | * @since 1.0.6 1544 | */ 1545 | add_filter( 'caldera_forms_submission_url', function( $url, $form_id ){ 1546 | $form = Caldera_Forms_Forms::get_form( $form_id ); 1547 | if( !empty( $form['is_connected_form'] ) ){ 1548 | $positon = cf_form_connector_get_current_position(); 1549 | 1550 | $current = $form_id; 1551 | if( ! empty( $positon[ $form_id ] ) ){ 1552 | $current = $positon[ $form_id ][ 'current_form' ]; 1553 | } 1554 | $url = add_query_arg( array( 'con_current' => $current, 'con_base' => $form_id ), $url ); 1555 | } 1556 | 1557 | return $url; 1558 | }, 50, 2); 1559 | 1560 | 1561 | 1562 | /** 1563 | * When submitting a advanced fiel field in a connected form, change form ID from connectef form to current form 1564 | * 1565 | * @since 1.0.6 1566 | * 1567 | * @uses "caldera_forms_get_form" action 1568 | * 1569 | * @param $form 1570 | * 1571 | * @return array|null 1572 | */ 1573 | function cf_conn_form_switch_form_for_file_upload( $form ){ 1574 | if( isset( $_REQUEST[ 'control' ], $_REQUEST[ 'con_current' ] ) ){ 1575 | set_query_var( 'cf_api', $_REQUEST[ 'con_current' ] ); 1576 | 1577 | remove_filter( 'caldera_forms_get_form', __FUNCTION__ ); 1578 | $form = Caldera_Forms_Forms::get_form( $_REQUEST[ 'con_current' ] ); 1579 | } 1580 | 1581 | return $form; 1582 | } 1583 | 1584 | 1585 | add_filter( 'caldera_forms_get_field_order', 'cf_conn_form_set_order_for_email', 25, 2 ); 1586 | function cf_conn_form_set_order_for_email( $order, $form ){ 1587 | if( isset( $form[ 'node' ] ) ){ 1588 | $fields = cf_form_connector_get_all_fields( $form ); 1589 | 1590 | if( ! empty( $fields ) ){ 1591 | $order = array_keys( $fields ); 1592 | } 1593 | } 1594 | 1595 | return $order; 1596 | } 1597 | 1598 | /** 1599 | * Get all fields of forms in sequence 1600 | * 1601 | * @since 1.0.8 1602 | * 1603 | * @param array $connected_form Connected form config 1604 | * 1605 | * @return array 1606 | */ 1607 | function cf_form_connector_get_all_fields( $connected_form ){ 1608 | $fields = array(); 1609 | 1610 | if( isset( $connected_form[ 'node' ] ) ) { 1611 | 1612 | foreach ( array_reverse( $connected_form[ 'node' ] ) as $connected_form ) { 1613 | $_form = Caldera_Forms_Forms::get_form( $connected_form[ 'form' ] ); 1614 | $fields = array_merge( Caldera_Forms_Forms::get_fields( $_form ), $fields ); 1615 | } 1616 | 1617 | } 1618 | 1619 | return $fields; 1620 | 1621 | } 1622 | 1623 | /** 1624 | * Override entry view UI for Connected Forms 1625 | * 1626 | * THIS IS A TERRIBLE HACK, I feel bad, it feels bad, it is bad. Also, it works. 1627 | * 1628 | * @since 1.0.8 1629 | * 1630 | * @uses "wp_ajax_get_entry" action 1631 | */ 1632 | function cf_form_connector_view_entry(){ 1633 | if( isset( $_POST, $_POST[ 'nonce' ], $_POST[ 'entry'], $_POST[ 'form' ] ) ){ 1634 | 1635 | $form = Caldera_Forms_Forms::get_form( strip_tags( $_POST[ 'form' ] ) ); 1636 | 1637 | if( empty( $form[ 'is_connected_form'] ) ){ 1638 | return; 1639 | } 1640 | 1641 | remove_action( 'wp_ajax_browse_entries', array( Caldera_Forms_Entry_UI::get_instance(), 'view_entries' ) ); 1642 | 1643 | $form[ 'fields' ] = cf_form_connector_get_all_fields( $form ); 1644 | 1645 | if( ! current_user_can( Caldera_Forms::get_manage_cap( 'entry-view', $form ) ) || ! wp_verify_nonce( $_POST[ 'nonce' ], 'cf_view_entry' ) ){ 1646 | wp_send_json_error( $_POST ); 1647 | } 1648 | 1649 | $entry_id = absint( $_POST[ 'entry' ] ); 1650 | 1651 | if( 0 < $entry_id && is_array( $form ) ){ 1652 | add_filter( 'caldera_forms_view_field_checkbox', function( $field_value, $field, $form ){ 1653 | //see: https://github.com/CalderaWP/Caldera-Forms/issues/1090 1654 | $_field_value = maybe_unserialize( str_replace( '"', '"', $field_value ) ); 1655 | if( is_array( $_field_value ) ){ 1656 | $field_value = ''; 1657 | foreach ( $_field_value as $opt => $opt_value ){ 1658 | $field_value .= $field[ 'config' ][ 'option' ][ $opt ][ 'label' ]; 1659 | } 1660 | 1661 | 1662 | } 1663 | return $field_value; 1664 | }, 25, 3 ); 1665 | $entry = Caldera_Forms::get_entry( $entry_id, $form ); 1666 | if( is_wp_error( $entry ) ){ 1667 | wp_send_json_error( $entry ); 1668 | }else{ 1669 | status_header( 200 ); 1670 | wp_send_json( $entry ); 1671 | } 1672 | }else{ 1673 | wp_send_json_error( $_POST ); 1674 | } 1675 | 1676 | 1677 | 1678 | } 1679 | 1680 | wp_send_json_error( $_POST ); 1681 | 1682 | } 1683 | 1684 | /** 1685 | * Parse {prev:*} magic tag 1686 | * 1687 | * @since 1.1.0 1688 | * 1689 | * @uses "caldera_forms_pre_do_bracket_magic" filter 1690 | * 1691 | * @param $return_value 1692 | * @param $tag 1693 | * @param $magics 1694 | * @param $entry_id 1695 | * @param $form 1696 | * 1697 | * @return mixed 1698 | */ 1699 | function cf_form_connector_prev_magic_tag( $return_value, $tag, $magics, $entry_id, $form ){ 1700 | if( 2 != count( $magics ) || ! isset( $magics[1][0] ) || false === strpos( $tag, '{prev' ) ){ 1701 | return $return_value; 1702 | } 1703 | $parts = explode( ':', $magics[1][0] ); 1704 | if ( empty( $parts[1] ) ) { 1705 | return $return_value; 1706 | } 1707 | 1708 | $slug_or_id = $parts[1]; 1709 | 1710 | $tracking = cf_form_connector_get_current_position(); 1711 | if( isset( $tracking[ $form[ 'ID'] ] ) ){ 1712 | $sequence = $tracking[ $form[ 'ID'] ]; 1713 | foreach ( $sequence[ 'fields' ] as $field_id => $field ){ 1714 | if( $slug_or_id === $field[ 'slug' ] ){ 1715 | if( isset( $sequence[ 'field_values' ][ $field['ID'] ] ) ){ 1716 | return $sequence[ 'field_values' ][ $field['ID'] ]; 1717 | 1718 | } 1719 | } 1720 | 1721 | } 1722 | 1723 | foreach ( $sequence[ 'field_values' ] as $field_id => $value ){ 1724 | if( $slug_or_id == $field_id ){ 1725 | return $value; 1726 | 1727 | } 1728 | 1729 | } 1730 | 1731 | } 1732 | 1733 | 1734 | 1735 | 1736 | 1737 | return $return_value; 1738 | 1739 | } 1740 | 1741 | /** 1742 | * Get field data for one form in connected form sequence 1743 | * 1744 | * @since 1.1.0 1745 | * 1746 | * @param array $sequence_data Current data for sequence 1747 | * @param string $current_form_id Current form ID 1748 | * 1749 | * @return array 1750 | */ 1751 | function cf_form_connector_current_fields( $sequence_data, $current_form_id ){ 1752 | if( ! isset( $sequence_data[ $current_form_id ] ) ){ 1753 | return array(); 1754 | } 1755 | $form = Caldera_Forms_Forms::get_form( $current_form_id ); 1756 | if( empty( $form ) ){ 1757 | return array(); 1758 | } 1759 | $fields = Caldera_Forms_Forms::get_fields( $form, false ); 1760 | $field_ids = wp_list_pluck( $fields, 'ID' ); 1761 | $field_values = array(); 1762 | foreach ( $sequence_data[ 'field_values'] as $field_id => $value ){ 1763 | if( in_array( $field_id, $field_ids ) ){ 1764 | $field_values[ $field_id ] = $value; 1765 | } 1766 | } 1767 | 1768 | return $field_values; 1769 | 1770 | 1771 | } 1772 | 1773 | /** 1774 | * Write the entry ID to sequence data 1775 | * 1776 | * @since 1.1.1 1777 | * 1778 | * @param int $entry_id Entry ID of sub-form 1779 | * @param string $base ID of connected form 1780 | * @param string $current ID of connected form. 1781 | */ 1782 | function cf_form_connected_write_id_to_progress( $entry_id, $base, $current ){ 1783 | $process_record = cf_form_connector_get_current_position(); 1784 | if ( ! empty( $process_record ) && isset( $process_record[ $base ] ) ) { 1785 | if ( ! isset( $process_record[ $base ][ $current ] ) ) { 1786 | $process_record[ $base ][ $current ] = array(); 1787 | } 1788 | $process_record[ $base ][ $current ][ 'id' ] = $entry_id; 1789 | } 1790 | cf_form_connector_set_current_position( $process_record ); 1791 | } 1792 | 1793 | 1794 | /** 1795 | * Make sure that the extra fields we add for progress are always hidden 1796 | * 1797 | * @since 1.1.1 1798 | */ 1799 | add_filter( 'caldera_forms_field_attributes', function( $attrs, $field, $form){ 1800 | if( isset( $attrs[ 'data-field' ] ) && 'cffld_stage' == $attrs[ 'data-field' ] ){ 1801 | $attrs[ 'type' ] = 'hidden'; 1802 | } 1803 | return $attrs; 1804 | }, 10, 3 ); 1805 | 1806 | 1807 | 1808 | -------------------------------------------------------------------------------- /includes/partial.php: -------------------------------------------------------------------------------- 1 | save(); 89 | 90 | } 91 | 92 | 93 | } -------------------------------------------------------------------------------- /includes/ptrack.php: -------------------------------------------------------------------------------- 1 | _input" name="" value="0"> 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /includes/templates/connection-builder.php: -------------------------------------------------------------------------------- 1 | $form_details ){ 6 | $form = \Caldera_Forms::get_form( $form_id ); 7 | if( !empty( $form['is_connected_form'] ) ){ 8 | continue; 9 | } 10 | if( !empty( $form['fields'] ) ){ 11 | foreach( $form['fields'] as $field_id=>$field ){ 12 | if( $field['type'] == 'html' ){ 13 | $form['fields'][ $field_id ]['config']['default'] = ''; 14 | } 15 | } 16 | } 17 | $forms[ $form_id ] = $form; 18 | } 19 | 20 | if( !empty( $element['condition_points']['conditions'] ) ){ 21 | foreach( $element['condition_points']['conditions'] as $condition_point ){ 22 | if( empty( $element['node'][ $condition_point['connect'] ] ) ){ 23 | // dont output points for nonexistant forms 24 | continue; 25 | } 26 | if( $condition_point['connect'] == $condition_point['parent'] ) { 27 | unset( $element['node'][ $condition_point['connect'] ] ); 28 | continue; 29 | } 30 | ?> 31 | 32 | 33 | 34 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | Add Form 47 | 48 | 49 | 50 | 51 | 52 | $node ) { 56 | if( ! isset( $forms[ $node[ 'form' ] ][ 'name' ] ) ) { 57 | $not_found = sprintf( 'Form %s Not Found.', $node[ 'form' ] ); 58 | printf( '%s', esc_html__( $not_found, 'cf-connected-forms' ) ); 59 | continue; 60 | } 61 | $location = explode( ',', $node['position'] ); 62 | 63 | ?> 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 83 | 84 | 85 | 86 | 171 | 182 | 190 | 197 | 198 | 322 | 590 | -------------------------------------------------------------------------------- /includes/templates/next_field.php: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /includes/templates/partials.php: -------------------------------------------------------------------------------- 1 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | /> 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /languages/cf-form-connector.pot: -------------------------------------------------------------------------------- 1 | #, fuzzy 2 | msgid "" 3 | msgstr "" 4 | "Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n" 5 | "Project-Id-Version: Connected Caldera Forms\n" 6 | "POT-Creation-Date: 2017-10-26 20:45+0200\n" 7 | "PO-Revision-Date: 2017-10-26 20:44+0200\n" 8 | "Last-Translator: New0 Nicolas Figueira \n" 9 | "Language-Team: New0 Nicolas Figueira \n" 10 | "MIME-Version: 1.0\n" 11 | "Content-Type: text/plain; charset=UTF-8\n" 12 | "Content-Transfer-Encoding: 8bit\n" 13 | "X-Generator: Poedit 2.0.4\n" 14 | "X-Poedit-Basepath: ..\n" 15 | "X-Poedit-Flags-xgettext: --add-comments=translators:\n" 16 | "X-Poedit-WPHeader: plugin.php\n" 17 | "X-Poedit-SourceCharset: UTF-8\n" 18 | "X-Poedit-KeywordsList: __;_e;_n:1,2;_x:1,2c;_ex:1,2c;_nx:4c,1,2;esc_attr__;" 19 | "esc_attr_e;esc_attr_x:1,2c;esc_html__;esc_html_e;esc_html_x:1,2c;_n_noop:1,2;" 20 | "_nx_noop:3c,1,2;__ngettext_noop:1,2\n" 21 | "X-Poedit-SearchPath-0: .\n" 22 | "X-Poedit-SearchPathExcluded-0: *.js\n" 23 | 24 | #: includes/functions.php:104 25 | msgid "Connected Form" 26 | msgstr "" 27 | 28 | #: includes/functions.php:149 29 | msgid "Connections" 30 | msgstr "" 31 | 32 | #: includes/functions.php:150 33 | msgid "Connected Forms Builder" 34 | msgstr "" 35 | 36 | #: includes/functions.php:157 37 | msgid "Partial Submissions" 38 | msgstr "" 39 | 40 | #: includes/functions.php:158 41 | msgid "Settings for partial submissions" 42 | msgstr "" 43 | 44 | #: includes/functions.php:1187 45 | msgid "Back" 46 | msgstr "" 47 | 48 | #: includes/functions.php:1222 49 | msgid "Next" 50 | msgstr "" 51 | 52 | #: includes/functions.php:1222 53 | msgid "Submit" 54 | msgstr "" 55 | 56 | #: includes/functions.php:1294 57 | msgid "Connected Forms" 58 | msgstr "" 59 | 60 | #: includes/functions.php:1295 61 | msgid "Connect multiple forms." 62 | msgstr "" 63 | 64 | #: includes/functions.php:1372 65 | msgid "Back Navigation --- Connected Forms" 66 | msgstr "" 67 | 68 | #: includes/functions.php:1374 includes/functions.php:1385 69 | msgid "Button" 70 | msgstr "" 71 | 72 | #: includes/functions.php:1375 73 | msgid "Move Backwards In A Connected Forms Sequence" 74 | msgstr "" 75 | 76 | #: includes/functions.php:1383 77 | msgid "Forward Navigation --- Connected Forms" 78 | msgstr "" 79 | 80 | #: includes/functions.php:1386 81 | msgid "Move Forwards In A Connected Forms Sequence" 82 | msgstr "" 83 | 84 | #: includes/templates/connection-builder.php:192 85 | #: includes/templates/connection-builder.php:310 86 | msgid "Add Condition" 87 | msgstr "" 88 | 89 | #: includes/templates/connection-builder.php:211 90 | msgid "Name" 91 | msgstr "" 92 | 93 | #: includes/templates/connection-builder.php:218 94 | msgid "Back Button" 95 | msgstr "" 96 | 97 | #: includes/templates/connection-builder.php:221 98 | msgid "Enable Back Navigation" 99 | msgstr "" 100 | 101 | #: includes/templates/connection-builder.php:227 102 | msgid "Conditions" 103 | msgstr "" 104 | 105 | #: includes/templates/connection-builder.php:231 106 | msgid "Add Conditional" 107 | msgstr "" 108 | 109 | #: includes/templates/connection-builder.php:237 110 | msgid "or" 111 | msgstr "" 112 | 113 | #: includes/templates/connection-builder.php:245 114 | msgid "if" 115 | msgstr "" 116 | 117 | #: includes/templates/connection-builder.php:247 118 | msgid "and" 119 | msgstr "" 120 | 121 | #: includes/templates/connection-builder.php:267 122 | msgid "is" 123 | msgstr "" 124 | 125 | #: includes/templates/connection-builder.php:270 126 | msgid "is not" 127 | msgstr "" 128 | 129 | #: includes/templates/connection-builder.php:273 130 | msgid "is greater than" 131 | msgstr "" 132 | 133 | #: includes/templates/connection-builder.php:276 134 | msgid "is less than" 135 | msgstr "" 136 | 137 | #: includes/templates/connection-builder.php:279 138 | msgid "starts with" 139 | msgstr "" 140 | 141 | #: includes/templates/connection-builder.php:282 142 | msgid "ends with" 143 | msgstr "" 144 | 145 | #: includes/templates/connection-builder.php:285 146 | msgid "contains" 147 | msgstr "" 148 | 149 | #: includes/templates/partials.php:13 150 | msgid "Active Partials" 151 | msgstr "" 152 | 153 | #: includes/templates/partials.php:23 154 | msgid "Enable" 155 | msgstr "" 156 | 157 | #: includes/templates/partials.php:26 158 | msgid "" 159 | "By default, entries in sequence will only be shown in entry viewer when " 160 | "sequence is completed. Check this option to show partial entries in the " 161 | "entry viewer." 162 | msgstr "" 163 | 164 | #: vendor/calderawp/dismissible-notice/src/Caldera_Warnings_Dismissible_Notice.php:129 165 | msgid "Dismiss this notice." 166 | msgstr "" 167 | 168 | #. Plugin Name of the plugin/theme 169 | msgid "Connected Caldera Forms" 170 | msgstr "" 171 | 172 | #. Plugin URI of the plugin/theme 173 | msgid "https://calderaforms.com/downloads/caldera-forms-connector" 174 | msgstr "" 175 | 176 | #. Description of the plugin/theme 177 | msgid "Connect multiple Caldera Forms into a sequence of forms" 178 | msgstr "" 179 | 180 | #. Author of the plugin/theme 181 | msgid "Caldera Labs" 182 | msgstr "" 183 | 184 | #. Author URI of the plugin/theme 185 | msgid "http://calderalabs.org" 186 | msgstr "" 187 | -------------------------------------------------------------------------------- /languages/fr_FR.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CalderaWP/cf-connected-forms/cc1f9316c04e0a0969ab836b57dac58a93351f46/languages/fr_FR.mo -------------------------------------------------------------------------------- /languages/fr_FR.po: -------------------------------------------------------------------------------- 1 | msgid "" 2 | msgstr "" 3 | "Plural-Forms: nplurals=2; plural=(n > 1);\n" 4 | "Project-Id-Version: Connected Caldera Forms\n" 5 | "POT-Creation-Date: 2017-10-26 20:19+0200\n" 6 | "PO-Revision-Date: 2017-10-26 20:37+0200\n" 7 | "Language-Team: \n" 8 | "MIME-Version: 1.0\n" 9 | "Content-Type: text/plain; charset=UTF-8\n" 10 | "Content-Transfer-Encoding: 8bit\n" 11 | "X-Generator: Poedit 2.0.4\n" 12 | "X-Poedit-Basepath: ..\n" 13 | "X-Poedit-Flags-xgettext: --add-comments=translators:\n" 14 | "X-Poedit-WPHeader: plugin.php\n" 15 | "X-Poedit-SourceCharset: UTF-8\n" 16 | "X-Poedit-KeywordsList: __;_e;_n:1,2;_x:1,2c;_ex:1,2c;_nx:4c,1,2;" 17 | "esc_attr__;esc_attr_e;esc_attr_x:1,2c;esc_html__;esc_html_e;" 18 | "esc_html_x:1,2c;_n_noop:1,2;_nx_noop:3c,1,2;__ngettext_noop:1,2\n" 19 | "Last-Translator: New0 Nicolas Figueira \n" 20 | "Language: fr_FR\n" 21 | "X-Poedit-SearchPath-0: .\n" 22 | "X-Poedit-SearchPathExcluded-0: *.js\n" 23 | 24 | #: includes/functions.php:104 25 | msgid "Connected Form" 26 | msgstr "Formulaires connectés" 27 | 28 | #: includes/functions.php:149 29 | msgid "Connections" 30 | msgstr "Connexions" 31 | 32 | #: includes/functions.php:150 33 | msgid "Connected Forms Builder" 34 | msgstr "Générateur de formulaires connectés" 35 | 36 | #: includes/functions.php:157 37 | msgid "Partial Submissions" 38 | msgstr "Soumissions partielles" 39 | 40 | #: includes/functions.php:158 41 | msgid "Settings for partial submissions" 42 | msgstr "Réglages des soumissions partielles" 43 | 44 | #: includes/functions.php:1141 45 | msgid "Back" 46 | msgstr "Retour" 47 | 48 | #: includes/functions.php:1161 49 | msgid "Next" 50 | msgstr "Suivant" 51 | 52 | #: includes/functions.php:1161 53 | msgid "Submit" 54 | msgstr "Soumettre" 55 | 56 | #: includes/functions.php:1225 57 | msgid "Connected Forms" 58 | msgstr "Formulaires connectés" 59 | 60 | #: includes/functions.php:1226 61 | msgid "Connect multiple forms." 62 | msgstr "Connecter plusieurs formulaires." 63 | 64 | #: includes/functions.php:1303 65 | msgid "Back Navigation --- Connected Forms" 66 | msgstr "Menu de retour --- Formulaires connectés" 67 | 68 | #: includes/functions.php:1305 includes/functions.php:1316 69 | msgid "Button" 70 | msgstr "Bouton" 71 | 72 | #: includes/functions.php:1306 73 | msgid "Move Backwards In A Connected Forms Sequence" 74 | msgstr "Reculer dans la navigation entre formulaire connectés" 75 | 76 | #: includes/functions.php:1314 77 | msgid "Forward Navigation --- Connected Forms" 78 | msgstr "Menu suivant --- Formulaires connectés" 79 | 80 | #: includes/functions.php:1317 81 | msgid "Move Forwards In A Connected Forms Sequence" 82 | msgstr "Avancer dans la navigation entre formulaires connectés" 83 | 84 | #: includes/templates/connection-builder.php:192 85 | #: includes/templates/connection-builder.php:310 86 | msgid "Add Condition" 87 | msgstr "Ajouter une condition" 88 | 89 | #: includes/templates/connection-builder.php:211 90 | msgid "Name" 91 | msgstr "Nom" 92 | 93 | #: includes/templates/connection-builder.php:218 94 | msgid "Back Button" 95 | msgstr "Bouton retour" 96 | 97 | #: includes/templates/connection-builder.php:221 98 | msgid "Enable Back Navigation" 99 | msgstr "Activer le bouton retour" 100 | 101 | #: includes/templates/connection-builder.php:227 102 | msgid "Conditions" 103 | msgstr "Conditions" 104 | 105 | #: includes/templates/connection-builder.php:231 106 | msgid "Add Conditional" 107 | msgstr "Ajouter condition" 108 | 109 | #: includes/templates/connection-builder.php:237 110 | msgid "or" 111 | msgstr "ou" 112 | 113 | #: includes/templates/connection-builder.php:245 114 | msgid "if" 115 | msgstr "si" 116 | 117 | #: includes/templates/connection-builder.php:247 118 | msgid "and" 119 | msgstr "et" 120 | 121 | #: includes/templates/connection-builder.php:267 122 | msgid "is" 123 | msgstr "est" 124 | 125 | #: includes/templates/connection-builder.php:270 126 | msgid "is not" 127 | msgstr "n'est pas" 128 | 129 | #: includes/templates/connection-builder.php:273 130 | msgid "is greater than" 131 | msgstr "est plus grand que" 132 | 133 | #: includes/templates/connection-builder.php:276 134 | msgid "is less than" 135 | msgstr "est inférieur à" 136 | 137 | #: includes/templates/connection-builder.php:279 138 | msgid "starts with" 139 | msgstr "commence par" 140 | 141 | #: includes/templates/connection-builder.php:282 142 | msgid "ends with" 143 | msgstr "termine par" 144 | 145 | #: includes/templates/connection-builder.php:285 146 | msgid "contains" 147 | msgstr "contient" 148 | 149 | #: includes/templates/partials.php:13 150 | msgid "Active Partials" 151 | msgstr "Activer les envois partiels" 152 | 153 | #: includes/templates/partials.php:23 154 | msgid "Enable" 155 | msgstr "Activer" 156 | 157 | #: includes/templates/partials.php:26 158 | msgid "" 159 | "By default, entries in sequence will only be shown in entry viewer when " 160 | "sequence is completed. Check this option to show partial entries in the " 161 | "entry viewer." 162 | msgstr "" 163 | "Par défaut, les données des formulaires apparaissent dans le tableau " 164 | "d'entrées lorsque le dernier formulaire est envoyé. En activant cette " 165 | "option, chaque formulaire sera enregistré dans le tableau d'entrées " 166 | "bien que la séquence ne soit pas complète." 167 | 168 | #: vendor/calderawp/dismissible-notice/src/Caldera_Warnings_Dismissible_Notice.php:129 169 | msgid "Dismiss this notice." 170 | msgstr "Supprimer cette avertissement." 171 | 172 | #. Plugin Name of the plugin/theme 173 | msgid "Connected Caldera Forms" 174 | msgstr "Caldera Forms connectés" 175 | 176 | #. Plugin URI of the plugin/theme 177 | msgid "https://calderaforms.com/downloads/caldera-forms-connector" 178 | msgstr "https://calderaforms.com/downloads/caldera-forms-connector" 179 | 180 | #. Description of the plugin/theme 181 | msgid "Connect multiple Caldera Forms into a sequence of forms" 182 | msgstr "" 183 | "Créez une suite de formulaires en séquence en connectant plusieurs " 184 | "formulaires Caldera Forms." 185 | 186 | #. Author of the plugin/theme 187 | msgid "Caldera Labs" 188 | msgstr "Caldera Labs" 189 | 190 | #. Author URI of the plugin/theme 191 | msgid "http://calderalabs.org" 192 | msgstr "http://calderalabs.org" 193 | -------------------------------------------------------------------------------- /naming-conventions.txt: -------------------------------------------------------------------------------- 1 | Plugin Name -- Form Connector For Caldera Forms 2 | Text domain -- cf-form-connector 3 | Function prefix -- cf_form_connector 4 | Class prefix - CF_Con_Form 5 | Root namespace -- n/a 6 | Filter Prefix -- cf_form_connector 7 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "cf-connected-forms", 3 | "version": "1.3.0-b-2", 4 | "description": "Connect multiple Caldera Forms into one sequence.", 5 | "repository": { 6 | "type": "git", 7 | "url": "https://github.com/CalderaWP/cf-connected-forms" 8 | }, 9 | "author": "CalderaWP", 10 | "license": "GPLv2+", 11 | "bugs": { 12 | "url": "https://github.com/CalderaWP/cf-connected-forms/issues" 13 | }, 14 | "devDependencies": { 15 | "grunt": "~0.4.2", 16 | "grunt-cli": "~0.1.11", 17 | "grunt-contrib-clean": "^0.6.0", 18 | "grunt-contrib-compress": "^0.13.0", 19 | "grunt-contrib-copy": "^0.7.0", 20 | "grunt-git": "^0.3.3", 21 | "grunt-shell": "^1.1.1", 22 | "grunt-text-replace": "^0.4.0", 23 | "gulp": "^3.9.0", 24 | "gulp-concat": "^2.6.0", 25 | "gulp-minify": "0.0.15", 26 | "gulp-sass": "^2.1.1", 27 | "gulp-sourcemaps": "^1.6.0", 28 | "gulp-watch": "^4.3.5" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /plugin.php: -------------------------------------------------------------------------------- 1 | =' ) ) { 58 | if ( is_admin() || defined( 'DOING_AJAX' ) && DOING_AJAX ) { 59 | include_once CF_FORM_CON_PATH . 'vendor/calderawp/dismissible-notice/src/functions.php'; 60 | } 61 | 62 | if ( is_admin() ) { 63 | //BIG nope nope nope! 64 | $message = __( sprintf( 'Connected Forms for Caldera Forms requires PHP version %1s or later. We strongly recommend PHP 5.5 or later for security and performance reasons. Current version is %2s.', '5.3.0', PHP_VERSION ), 'cf-form-connector' ); 65 | echo caldera_warnings_dismissible_notice( $message, true, 'activate_plugins', 'con_forms_php_ver' ); 66 | } 67 | 68 | }else{ 69 | // load dependencies 70 | include_once trailingslashit( CF_FORM_CON_PATH ) . 'vendor/autoload.php'; 71 | include trailingslashit( CF_FORM_CON_PATH ) . 'includes/functions.php'; 72 | include trailingslashit( CF_FORM_CON_PATH ) . 'includes/partial.php'; 73 | include trailingslashit( CF_FORM_CON_PATH ) . 'includes/ptrack.php'; 74 | include trailingslashit( CF_FORM_CON_PATH ) . 'includes/calcdefaults.php'; 75 | add_filter('caldera_forms_get_form_processors', 'cf_form_connector_register'); 76 | 77 | } 78 | 79 | } 80 | -------------------------------------------------------------------------------- /readme.txt: -------------------------------------------------------------------------------- 1 | === Form Connector For Caldera Forms === 2 | Contributors: Shelob9 3 | Donate link: https://CalderaWP.com 4 | Tags: forms, caldera forms, Caldera Forms, wpform 5 | Requires at least: 4.3 6 | Tested up to: 4.5 7 | Stable tag: 1.0.4 8 | License: GPLv2 or later 9 | License URI: http://www.gnu.org/licenses/gpl-2.0.html 10 | 11 | 12 | 13 | == Changelog == 14 | 15 | = 1.0.4 = 16 | Added the magic tag {prev:field_slug} or {prev:field_id} to return previous field values 17 | Fixed issue preventing multi-page forms to function in connected forms sequences. 18 | 19 | = 1.0.3 = 20 | Improved compatibility with core plugin version 1.3.2+ 21 | 22 | = 1.0.2 = 23 | * Fixed bug affecting entry output. 24 | 25 | = 1.0.1 = 26 | * Fix bug preventing forms without conditional logic from being loaded. 27 | 28 | = 1.0.0 = 29 | * Initial release 30 | -------------------------------------------------------------------------------- /releases/cf-connected-forms-0.2.1.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CalderaWP/cf-connected-forms/cc1f9316c04e0a0969ab836b57dac58a93351f46/releases/cf-connected-forms-0.2.1.zip -------------------------------------------------------------------------------- /releases/cf-connected-forms-1.0.0.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CalderaWP/cf-connected-forms/cc1f9316c04e0a0969ab836b57dac58a93351f46/releases/cf-connected-forms-1.0.0.zip -------------------------------------------------------------------------------- /releases/cf-connected-forms-1.0.1.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CalderaWP/cf-connected-forms/cc1f9316c04e0a0969ab836b57dac58a93351f46/releases/cf-connected-forms-1.0.1.zip -------------------------------------------------------------------------------- /releases/cf-connected-forms-1.0.2-b-1.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CalderaWP/cf-connected-forms/cc1f9316c04e0a0969ab836b57dac58a93351f46/releases/cf-connected-forms-1.0.2-b-1.zip -------------------------------------------------------------------------------- /releases/cf-connected-forms-1.0.2.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CalderaWP/cf-connected-forms/cc1f9316c04e0a0969ab836b57dac58a93351f46/releases/cf-connected-forms-1.0.2.zip -------------------------------------------------------------------------------- /releases/cf-connected-forms-1.0.3.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CalderaWP/cf-connected-forms/cc1f9316c04e0a0969ab836b57dac58a93351f46/releases/cf-connected-forms-1.0.3.zip -------------------------------------------------------------------------------- /releases/cf-connected-forms-1.0.4-b1.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CalderaWP/cf-connected-forms/cc1f9316c04e0a0969ab836b57dac58a93351f46/releases/cf-connected-forms-1.0.4-b1.zip -------------------------------------------------------------------------------- /releases/cf-connected-forms-1.0.4.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CalderaWP/cf-connected-forms/cc1f9316c04e0a0969ab836b57dac58a93351f46/releases/cf-connected-forms-1.0.4.zip -------------------------------------------------------------------------------- /releases/cf-connected-forms-1.0.5-rc1.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CalderaWP/cf-connected-forms/cc1f9316c04e0a0969ab836b57dac58a93351f46/releases/cf-connected-forms-1.0.5-rc1.zip -------------------------------------------------------------------------------- /releases/cf-connected-forms-1.0.5.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CalderaWP/cf-connected-forms/cc1f9316c04e0a0969ab836b57dac58a93351f46/releases/cf-connected-forms-1.0.5.zip -------------------------------------------------------------------------------- /releases/cf-connected-forms-1.0.6.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CalderaWP/cf-connected-forms/cc1f9316c04e0a0969ab836b57dac58a93351f46/releases/cf-connected-forms-1.0.6.zip -------------------------------------------------------------------------------- /releases/cf-connected-forms-1.0.7-b-1.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CalderaWP/cf-connected-forms/cc1f9316c04e0a0969ab836b57dac58a93351f46/releases/cf-connected-forms-1.0.7-b-1.zip -------------------------------------------------------------------------------- /releases/cf-connected-forms-1.0.7.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CalderaWP/cf-connected-forms/cc1f9316c04e0a0969ab836b57dac58a93351f46/releases/cf-connected-forms-1.0.7.zip -------------------------------------------------------------------------------- /releases/cf-connected-forms-1.0.8.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CalderaWP/cf-connected-forms/cc1f9316c04e0a0969ab836b57dac58a93351f46/releases/cf-connected-forms-1.0.8.zip -------------------------------------------------------------------------------- /releases/cf-connected-forms-1.1.0-b-1.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CalderaWP/cf-connected-forms/cc1f9316c04e0a0969ab836b57dac58a93351f46/releases/cf-connected-forms-1.1.0-b-1.zip -------------------------------------------------------------------------------- /releases/cf-connected-forms-1.1.0.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CalderaWP/cf-connected-forms/cc1f9316c04e0a0969ab836b57dac58a93351f46/releases/cf-connected-forms-1.1.0.zip -------------------------------------------------------------------------------- /releases/cf-connected-forms-1.1.1-b-1.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CalderaWP/cf-connected-forms/cc1f9316c04e0a0969ab836b57dac58a93351f46/releases/cf-connected-forms-1.1.1-b-1.zip -------------------------------------------------------------------------------- /releases/cf-connected-forms-1.1.1-rc-1.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CalderaWP/cf-connected-forms/cc1f9316c04e0a0969ab836b57dac58a93351f46/releases/cf-connected-forms-1.1.1-rc-1.zip -------------------------------------------------------------------------------- /releases/cf-connected-forms-1.1.1.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CalderaWP/cf-connected-forms/cc1f9316c04e0a0969ab836b57dac58a93351f46/releases/cf-connected-forms-1.1.1.zip -------------------------------------------------------------------------------- /releases/cf-connected-forms-1.2.0.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CalderaWP/cf-connected-forms/cc1f9316c04e0a0969ab836b57dac58a93351f46/releases/cf-connected-forms-1.2.0.zip -------------------------------------------------------------------------------- /releases/cf-connected-forms-1.2.1-b-1.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CalderaWP/cf-connected-forms/cc1f9316c04e0a0969ab836b57dac58a93351f46/releases/cf-connected-forms-1.2.1-b-1.zip -------------------------------------------------------------------------------- /releases/cf-connected-forms-1.2.1.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CalderaWP/cf-connected-forms/cc1f9316c04e0a0969ab836b57dac58a93351f46/releases/cf-connected-forms-1.2.1.zip -------------------------------------------------------------------------------- /releases/cf-connected-forms-1.2.2-b-1.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CalderaWP/cf-connected-forms/cc1f9316c04e0a0969ab836b57dac58a93351f46/releases/cf-connected-forms-1.2.2-b-1.zip -------------------------------------------------------------------------------- /releases/cf-connected-forms-1.2.2.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CalderaWP/cf-connected-forms/cc1f9316c04e0a0969ab836b57dac58a93351f46/releases/cf-connected-forms-1.2.2.zip -------------------------------------------------------------------------------- /releases/cf-connected-forms-1.3.0-b-1.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CalderaWP/cf-connected-forms/cc1f9316c04e0a0969ab836b57dac58a93351f46/releases/cf-connected-forms-1.3.0-b-1.zip -------------------------------------------------------------------------------- /releases/cf-connected-forms-1.3.0-b-2.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CalderaWP/cf-connected-forms/cc1f9316c04e0a0969ab836b57dac58a93351f46/releases/cf-connected-forms-1.3.0-b-2.zip -------------------------------------------------------------------------------- /releases/cf-form-connector-0.1.0.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CalderaWP/cf-connected-forms/cc1f9316c04e0a0969ab836b57dac58a93351f46/releases/cf-form-connector-0.1.0.zip -------------------------------------------------------------------------------- /releases/cf-form-connector-0.2.0.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CalderaWP/cf-connected-forms/cc1f9316c04e0a0969ab836b57dac58a93351f46/releases/cf-form-connector-0.2.0.zip --------------------------------------------------------------------------------
26 | 27 |