Notes for implementing a Javascript CRUD interface with WordPress
We are trying to maintain a generic implementation. Using a JSON string as the data packet offers two-fold benefits: it can hold any data, and simple to copy without dealing with deep cloning of objects.
CB – callback function
onS – on Success
onE – on Error
ctrl – Controller
mdl – Model
SS – Storage Service
NOTES: There will be ID and post_ID. Post_ID will also be in the JSON package. Most of the time they would be equal, but they could be separated.
Not sure if separation of mdl and SS is necessary, yet.
Should Controller send a unique transaction ID down the chain so a log can be created to record steps in transaction or create a journal.
Code to generate pseudo-unique id
function guid() {
function s4() {
return Math.floor((1 + Math.random()) * 0x10000)
.toString(16)
.substring(1);
}
return s4() + s4() + '-' + s4() + '-' + s4() + '-' +
s4() + '-' + s4() + s4() + s4();
}
Model element data = {
ID : id goes here,
data : { } ,
state: 'uploaded', 'error', 'uploading', etc
}
Model.data = an array of model element data
StorageService data = {
ID : id goes here,
data : JSON string,
state: 'uploaded', etc
}
ERRORS
CREATE
Model has a NewE object the data-binding is set on so it contains new entry
- Controller Add to Model with ctrlCBonS and ctrlCBonE
- Model sends JSON.stringify of New Entry with mdlCBonS and mdlCBonE to StorageService
- StorageService ajax request to ‘create_action’ url with SSCBonS and SSCBonE.
- on success SSCBonS is called
- A new object with returned ID, JSON of New Entry, and state of ‘uploaded’ is pushed to SS collection
- (could we have SS push new object directly to Model?)
- mdlCBonS is called with new object
- JSON.parse new object data and push to model collection
- Clear NewE object
- ctrlCBonS is called with new ID
- on error SSCBonE is called
- push error to SS error object
- mdlCBons is called with clone of error object
- error added to error object
- ctrlCBonE is called with error object – since async may not want ctrl to access error thru model
- on success SSCBonS is called
READ
getAll()
get(id)
get([id1,id2,id3,id4])
get(page, posts_per_page)
findByTitle(‘ipsum’)
findByAuthor(‘bob’)
showAll
show(id)
show([id1,id2,id3,id4])
show(page, posts_per_page)
model.show* – these will bring down a subset of StorageService’s collection
SS.get* – these will send ajax request to obtain a new collection
model.showAll(b) – copy all of SS collection into model. If b is true, run getAll() and copy into SS and model
model.show(id) – find id in SS collection, if not found, get(id) called, if found added to SS and model
UPDATE
Controller is called with ID of data to change
- Controller Update to Model with ID, ctrlCBonS, and ctrlCBonE
- Model finds entry with ID (async?) JSON.stringify data, state changed to ‘saving’
- Model sends ID and JSON string to StorageService with mdlCBonS and mdlCBonE
- StorageService finds ID
- JSON.parse SS and model versions, run _.isEqual
- if equal
- if state is ‘saved’
- call mdlCBonS with state
- mdlCBonS updates state
- ctrlCBonS is called
- else
- state is changed to ‘saving’
- StorageService sends ajax request to ‘update_action’ with SSCBonS and SSCBonE
- on success SSCBonS is called
- state is changed to saved
- mdlCBonS is called with state
- state of model is changed to state
- ctlCBonS is called with state
- on error SSCBonE is called
- state is changed to ‘notSaved’
- mdlCBonE is called with state
- state of model is changed to state
- ctlCBonS is called with state
- if equal
Ok, after going through all the possible READ methods, getting overwhelmed. These are things that can be implemented later if needed. For now, let’s leave the above info/data/notes but continue on with a more abridged solution.
Beginning Basic Storage Service API
SS = {
create(id, data,[CBonS, CBonE]),
read(CBonS, CBonE), // data passed to CBonS
update(id, data, [CBonS, CBonE]),
delete(id, [CBonS, CBonE])
}
No data returned by these functions as they are asynchronous. Data passed to callbacks, CB. Above we were looking at SS having a collection. Let’s simplify..only model now. An SS collection would act like a cache. Let’s look/implement at it in that way later.
CREATE
SS.create
Model has a NewE object the data-binding is set on so it contains new entry
- Controller Add to Model with ctrlCBonS and ctrlCBonE
- Model sends JSON.stringify of New Entry with mdlCBonS and mdlCBonE to SS.create
- StorageService ajax request to ‘create_action’ url with SSCBonS and SSCBonE.
- on success SSCBonS is called
- A new object with returned ID, JSON of New Entry, and state of ‘saved’ is created
- mdlCBonS is called with new object
- JSON.parse new object data and push to model collection
- ctrlCBonS is called with new ID
- on error SSCBonE is called with error
- mdlCBons is called with error object – maybe as JSON
- maybe—-error added to error object
- ctrlCBonE is called with error object – since async may not want ctrl to access error thru model
- on success SSCBonS is called
READ
SS.read
Either through controller or part of initialization of app, read is called.
1. Controller or init calls model.read() with ctrlCBonS and ctrlCBonE
2. Model.read calls SS.read with mdlCBonS and mdlCBonE
3. StorageService ajax request to ‘read_action’ url with SSCBonS and SSCBonE
* on success SSCBonS is called with data
1. a JSON array is returned.
2. An array of objects is created. For each element in the JSON array an object like SS data object above is created. data property on object is still in JSON format. state is set to ‘saved’ for each.
3. This new array of objects is passed to mdlCBonS
1. mdlCBonS goes through and JSON.parse the data property
2. Model’s data is set to this array of objects
3. mdlCBonS calls ctrlCBonS
* on error SSCBonE is called with error
2. mdlCBons is called with error object – maybe as JSON
1. maybe—-error added to error object
2. ctrlCBonE is called with error object – since async may not want ctrl to access error thru model
On PHP side. Send only ID and any field that is needed..not to include the minutia of fields especially since unsure how the conversions from JSON and back might affect the fields..esp. dates.
UPDATE
SS.update
Controller is called with ID of data to change.
- Controller Update to Model with ID, ctrlCBonS, and ctrlCBonE
- Model finds entry with ID, JSON.stringify data, state changed to ‘saving’
- Model element data object in closure so accessed by CB’s
- Model sends ID and JSON string to StorageService with mdlCBonS and mdlCBonE
- StorageService sends ajax request to ‘update_action’ with SSCBonS and SSCBonE
- on success SSCBonS is called with result
- mdlCBonS is called with state
- state of model is changed to state, ‘saved’
- ctlCBonS is called with state
- mdlCBonS is called with state
- on error SSCBonE is called
- mdlCBonE is called with state
- state of model is changed to state, ‘notSaved’
- ctlCBonS is called with state
- mdlCBonE is called with state
- on success SSCBonS is called with result
On PHP side wp_update_post( $post, $wp_error ); is called where $post is an associative array with ‘ID’, and any fields that are changing. We will use JSON.decode($string, true), true tells it to return an associative array.
DELETE
SS.delete
- Controller Delete model with ID, ctrlCBonS, and ctrlCBonE
- Model delete finds entry with ID, state changes to ‘deleting’ (_.find)
- Model sends ID to SS with mdlCBonS and mdlCBonE
- StorageService sends ajax request to ‘delete_action’ with SSCBonS and SSCBonE
- on success SSCBonS is called with result
- mdlCBonS is called with state
- model = _.filter(model, function(e){return e.ID !== ID});
- on error SSCBonE is called with result
- if result === ‘postID not found’
mdlCBonS is called with state- see above – ID is removed from model
- else
mdlCBonE is called with ‘unableToDelete’- state is changed
- if result === ‘postID not found’
- on success SSCBonS is called with result
On PHP side wp_delete_post( $postID, $force_delete ) is called. Returns $post if success or false if failure. Look at whether we should bypass trash#Notes for implementing a Javascript CRUD interface with WordPress#
We are trying to maintain a generic implementation. Using a JSON string as the data packet offers two-fold benefits: it can hold any data, and simple to copy without dealing with deep cloning of objects.
CB – callback function
onS – on Success
onE – on Error
ctrl – Controller
mdl – Model
SS – Storage Service
NOTES: There will be ID and post_ID. Post_ID will also be in the JSON package. Most of the time they would be equal, but they could be separated.
Not sure if separation of mdl and SS is necessary, yet.
Should Controller send a unique transaction ID down the chain so a log can be created to record steps in transaction or create a journal.
Code to generate pseudo-unique id
function guid() {
function s4() {
return Math.floor((1 + Math.random()) * 0x10000)
.toString(16)
.substring(1);
}
return s4() + s4() + '-' + s4() + '-' + s4() + '-' +
s4() + '-' + s4() + s4() + s4();
}
Model element data = {
ID : id goes here,
data : { } ,
state: 'uploaded', 'error', 'uploading', etc
}
Model.data = an array of model element data
StorageService data = {
ID : id goes here,
data : JSON string,
state: 'uploaded', etc
}
ERRORS
CREATE
Model has a NewE object the data-binding is set on so it contains new entry
- Controller Add to Model with ctrlCBonS and ctrlCBonE
- Model sends JSON.stringify of New Entry with mdlCBonS and mdlCBonE to StorageService
- StorageService ajax request to ‘create_action’ url with SSCBonS and SSCBonE.
- on success SSCBonS is called
- A new object with returned ID, JSON of New Entry, and state of ‘uploaded’ is pushed to SS collection
- (could we have SS push new object directly to Model?)
- mdlCBonS is called with new object
- JSON.parse new object data and push to model collection
- Clear NewE object
- ctrlCBonS is called with new ID
- on error SSCBonE is called
- push error to SS error object
- mdlCBons is called with clone of error object
- error added to error object
- ctrlCBonE is called with error object – since async may not want ctrl to access error thru model
- on success SSCBonS is called
READ
getAll()
get(id)
get([id1,id2,id3,id4])
get(page, posts_per_page)
findByTitle(‘ipsum’)
findByAuthor(‘bob’)
showAll
show(id)
show([id1,id2,id3,id4])
show(page, posts_per_page)
model.show* – these will bring down a subset of StorageService’s collection
SS.get* – these will send ajax request to obtain a new collection
model.showAll(b) – copy all of SS collection into model. If b is true, run getAll() and copy into SS and model
model.show(id) – find id in SS collection, if not found, get(id) called, if found added to SS and model
UPDATE
Controller is called with ID of data to change
- Controller Update to Model with ID, ctrlCBonS, and ctrlCBonE
- Model finds entry with ID (async?) JSON.stringify data, state changed to ‘saving’
- Model sends ID and JSON string to StorageService with mdlCBonS and mdlCBonE
- StorageService finds ID
- JSON.parse SS and model versions, run _.isEqual
- if equal
- if state is ‘saved’
- call mdlCBonS with state
- mdlCBonS updates state
- ctrlCBonS is called
- else
- state is changed to ‘saving’
- StorageService sends ajax request to ‘update_action’ with SSCBonS and SSCBonE
- on success SSCBonS is called
- state is changed to saved
- mdlCBonS is called with state
- state of model is changed to state
- ctlCBonS is called with state
- on error SSCBonE is called
- state is changed to ‘notSaved’
- mdlCBonE is called with state
- state of model is changed to state
- ctlCBonS is called with state
- if equal
Ok, after going through all the possible READ methods, getting overwhelmed. These are things that can be implemented later if needed. For now, let’s leave the above info/data/notes but continue on with a more abridged solution.
Beginning Basic Storage Service API
SS = {
create(id, data,[CBonS, CBonE]),
read(CBonS, CBonE), // data passed to CBonS
update(id, data, [CBonS, CBonE]),
delete(id, [CBonS, CBonE])
}
No data returned by these functions as they are asynchronous. Data passed to callbacks, CB. Above we were looking at SS having a collection. Let’s simplify..only model now. An SS collection would act like a cache. Let’s look/implement at it in that way later.
CREATE
SS.create
Model has a NewE object the data-binding is set on so it contains new entry
- Controller Add to Model with ctrlCBonS and ctrlCBonE
- Model sends JSON.stringify of New Entry with mdlCBonS and mdlCBonE to SS.create
- StorageService ajax request to ‘create_action’ url with SSCBonS and SSCBonE.
- on success SSCBonS is called
- A new object with returned ID, JSON of New Entry, and state of ‘saved’ is created
- mdlCBonS is called with new object
- JSON.parse new object data and push to model collection
- ctrlCBonS is called with new ID
- on error SSCBonE is called with error
- mdlCBons is called with error object – maybe as JSON
- maybe—-error added to error object
- ctrlCBonE is called with error object – since async may not want ctrl to access error thru model
- on success SSCBonS is called
READ
SS.read
Either through controller or part of initialization of app, read is called.
1. Controller or init calls model.read() with ctrlCBonS and ctrlCBonE
2. Model.read calls SS.read with mdlCBonS and mdlCBonE
3. StorageService ajax request to ‘read_action’ url with SSCBonS and SSCBonE
* on success SSCBonS is called with data
1. a JSON array is returned.
2. An array of objects is created. For each element in the JSON array an object like SS data object above is created. data property on object is still in JSON format. state is set to ‘saved’ for each.
3. This new array of objects is passed to mdlCBonS
1. mdlCBonS goes through and JSON.parse the data property
2. Model’s data is set to this array of objects
3. mdlCBonS calls ctrlCBonS
* on error SSCBonE is called with error
2. mdlCBons is called with error object – maybe as JSON
1. maybe—-error added to error object
2. ctrlCBonE is called with error object – since async may not want ctrl to access error thru model
On PHP side. Send only ID and any field that is needed..not to include the minutia of fields especially since unsure how the conversions from JSON and back might affect the fields..esp. dates.
UPDATE
SS.update
Controller is called with ID of data to change.
- Controller Update to Model with ID, ctrlCBonS, and ctrlCBonE
- Model finds entry with ID, JSON.stringify data, state changed to ‘saving’
- Model element data object in closure so accessed by CB’s
- Model sends ID and JSON string to StorageService with mdlCBonS and mdlCBonE
- StorageService sends ajax request to ‘update_action’ with SSCBonS and SSCBonE
- on success SSCBonS is called with result
- mdlCBonS is called with state
- state of model is changed to state, ‘saved’
- ctlCBonS is called with state
- mdlCBonS is called with state
- on error SSCBonE is called
- mdlCBonE is called with state
- state of model is changed to state, ‘notSaved’
- ctlCBonS is called with state
- mdlCBonE is called with state
- on success SSCBonS is called with result
On PHP side wp_update_post( $post, $wp_error ); is called where $post is an associative array with ‘ID’, and any fields that are changing. We will use JSON.decode($string, true), true tells it to return an associative array.
DELETE
SS.delete
- Controller Delete model with ID, ctrlCBonS, and ctrlCBonE
- Model delete finds entry with ID, state changes to ‘deleting’ (_.find)
- Model sends ID to SS with mdlCBonS and mdlCBonE
- StorageService sends ajax request to ‘delete_action’ with SSCBonS and SSCBonE
- on success SSCBonS is called with result
- mdlCBonS is called with state
- model = _.filter(model, function(e){return e.ID !== ID});
- on error SSCBonE is called with result
- if result === ‘postID not found’
mdlCBonS is called with state- see above – ID is removed from model
- else
mdlCBonE is called with ‘unableToDelete’- state is changed
- if result === ‘postID not found’
- on success SSCBonS is called with result
On PHP side wp_delete_post( $postID, $force_delete ) is called. Returns $post if success or false if failure. Look at whether we should bypass trash