<?xml version="1.0" encoding="UTF-8"?>
<Export generator="Cache" version="25" zv="Cache for Windows (x86-64) 2016.2 (Build 640)" ts="2016-04-29 13:00:27">
<Class name="DO.Review">
<Description>
Created using the page template: Title Page</Description>
<Super>%ZEN.Component.page</Super>
<TimeChanged>64037,46734.878162</TimeChanged>
<TimeCreated>63993,41677.118728</TimeCreated>

<Parameter name="APPLICATION">
<Description>
Class name of application this page belongs to.</Description>
</Parameter>

<Parameter name="PAGENAME">
<Description>
Displayed name of this page.</Description>
<Default>Review</Default>
</Parameter>

<Parameter name="DOMAIN">
<Description>
Domain used for localization.</Description>
</Parameter>

<XData name="Style">
<Description>
This Style block contains page-specific CSS style definitions.</Description>
<Data><![CDATA[
<style type="text/css">
/* style for title bar */
#title {
	background: lightblue;
	color: black;
	font-family: Verdana;
	font-size: 1.5em;
	font-weight: bold;
	padding: 5px;
	border-bottom: 1px solid black;
	text-align: center;
}

/* Style applied to body of page. */
body {	background-color: #D6D6D6	;}

.vtLabelLeft {
	color:black; 
	font-family:Verdana; 
	font-size:12pt;
}

.goodText, a.radioSetCaption, span.checkboxCaption {
	color:black; 
	padding:5px; 
	font-family:Verdana; 
	font-size:10pt;
}

/* Style for button. */
.button {
	color:green;
	padding:5px;
	font-family:Verdana;
	border-width: 4px;
	border-radius: 40px;
	box-shadow: 5px 5px 2px #666666;
}

</style>
]]></Data>
</XData>

<XData name="Contents">
<Description>
This XML block defines the contents of this page.</Description>
<XMLNamespace>http://www.intersystems.com/zen</XMLNamespace>
<Data><![CDATA[
<page xmlns="http://www.intersystems.com/zen" title="Restaurant Reviews">
<label id="title" value="Good Food Restaurant Reviews"/>
<hgroup id="note">
<text id="noteText" hidden="true"/>
</hgroup>
<hgroup width="90%" align="center" >
<spacer height="350px"/>
<vgroup width="60%" labelPosition="left" >
<text id="txtName" label="Your name" height="50px" valign="top" controlClass="goodText"/>
<textarea id="txtReview" label="Your review"  spellcheck="true" cols="40" rows="10" controlClass="goodText"/>
<radioSet id="radioRating" label="Rating " valueList="Terrible,Poor,Average,Good,Excellent"
          height="50px" valign="bottom" />
</vgroup>
<vgroup width="20%" >
<label value="Tags" controlClass="vtLabelLeft"/>
<checkbox id="chk0" caption="Family Friendly"/>
<checkbox id="chk1" caption="Romantic"/>
<checkbox id="chk2" caption="Business"/>
<checkbox id="chk3" caption="Friends"/>
<spacer height="30px"/>
<button id="btnDone" caption="Done!" controlStyle="font-size:20px" onclick="zenPage.makeJSON();"/>
</vgroup>
<vgroup width="10%" labelPosition="left" valign="top">
<spacer height="20px"/>
<textarea id="txtJSON" label="JSON from client" cols="50" rows="4" readOnly="true" controlClass="goodText"/>
</vgroup>
</hgroup>
<hgroup align="center">
<textarea id="reviews" label="Raw Reviews: " cols="100" rows="8" readOnly="true" controlClass="goodText" />
</hgroup>
</page>
]]></Data>
</XData>

<Method name="makeJSON">
<Language>javascript</Language>
<ClientMethod>1</ClientMethod>
<Implementation><![CDATA[
	try {
		var name = zen('txtName').getValue();
		var reviewText = zen('txtReview').getValue();
		var rating = zen('radioRating').getValue();
		var tags = ['Family','Romantic','Business','Friends'];
		var taglist = '';

		for (var i = 3; i >= 0; i--) {
			var id = 'chk' + i; 
			if (zen(id).getValue() == false) { tags.splice(i, 1); }
			else { taglist = tags[i] + ',' + taglist; }
		}
		
		// Create JSON on the client
		var objReview = {"reviewer" : name, "rating" : rating, "review" : reviewText, "tags" : tags}
		var strReview = JSON.stringify(objReview);
		zen('txtJSON').setValue(strReview);
				
		// send JSON to the server
		var response = zenPage.StoreJSON(strReview); //send JSON string 
		var responseObject = JSON.parse(response);
		alert(JSON.stringify(responseObject));
		
		// get JSON reviews
		var allReviews = zenPage.CreateJSONfromDocDBReviews();
		zen('reviews').setValue(allReviews);
		/*
		//If time permits, loops through and dynamically add elements for formatted reviews
		var sg=zen("vg");
	 	var dg=zenPage.createComponent("label");
		dg.value = googleReviews; 

		sg.addChild(dg);
		sg.refreshContents(1)*/
		
	}
	catch (ex) {
		zenExceptionHandler(ex,arguments);
	}
]]></Implementation>
</Method>

<Method name="StoreJSON">
<ClassMethod>1</ClassMethod>
<FormalSpec>JSONstring</FormalSpec>
<ReturnType>%String</ReturnType>
<ZenMethod>1</ZenMethod>
<Implementation><![CDATA[
	try {
		//1. Create dynamic Object from JSONstring.
		set dynamicObject = ##class(%AbstractObject).$fromJSON(JSONstring)
		
		//2. Modify the contents by adding a timestamp and setting source
		do dynamicObject.$set("timestamp",$zdatetime($h,3))
		set dynamicObject.source = "website"
		//do dynamicObject.$delete("tags") -- $delete will be 2016.3 or later

		//3. Get review number based on size
		set db = ##class(%DataModel.Document.Database).$getDatabase()
		set googleCollection = db.$getCollection("googlereviews")
		set websiteCollection= db.$getCollection("websitereviews")
		set size = googleCollection.$size() + websiteCollection.$size()
		do dynamicObject.$set("reviewnumber",size)
		
		//4. Save in the doc database	
		do websiteCollection.$insert(dynamicObject)	
			
		//ADD IN LESSON 3: Save as persistent objects instead of doc db
		//     could create object and manually map w/ serial property for tags, then %Save()
		//     come back and use $compose to create an object dynamically
		set reviewPersist = dynamicObject.$compose("Restaurant.Reviews")
		set status = reviewPersist.%Save()
		
		//5. Create feedback text based on the rating
		if ((dynamicObject.rating = "Excellent") || (dynamicObject.rating = "Good") || (dynamicObject.rating="Average")) 
		{
			//Create dynamic object	using $new and setting
			set responseObject = ##class(%Object).$new()
			do responseObject.$set("message","Thanks for your great review!")
			return responseObject.$toJSON()
		}
		else {
			//Alternate quickhand way to create a dynamic object
			set responseObject = {"message":"Thanks for your review. Please come again so we can make it up to you!"}
			return responseObject.$toJSON()	
		}
	}
	catch(ex){
		set responseObject = {}
		do responseObject.$set("message","JSON message: *"_JSONstring_"* is invalid.")
		return responseObject
		
 	}
	quit
]]></Implementation>
</Method>

<Method name="CreateJSONfromDocDBReviews">
<Description>
Background: Data has been retrieved from google on page load and stored in doc DB to make it the most up to date.
Purpose: Create JSON from Doc DB reviews to put on webpage.</Description>
<ClassMethod>1</ClassMethod>
<ReturnType>%String</ReturnType>
<ZenMethod>1</ZenMethod>
<Implementation><![CDATA[
	//1. Create dynamic array to hold reviews
	set reviewArray = [] //Same as: set reviewArray = ##class(%Array).$new()  
	
	//2. Get google reviews from doc db
	set db = ##class(%DataModel.Document.Database).$getDatabase()
	set googleCollection = db.$getCollection("googlereviews")

	//3. Iterate through google reviews, parse and putting in new dynamic object since we want a different format
	set i= googleCollection.$getIterator()
	while i.$getNext(.key,.value) {
		set value = googleCollection.$get(key)
		set newReviewObject = {} //Same as: set newReviewObject = ##class(%Object).$new()
		set newReviewObject.reviewnumber = key
		set newReviewObject.rating = value.rating
		set newReviewObject.reviewer = value."author_name"
		set newReviewObject.review = value.text
		set newReviewObject.timestamp = value.time
		set newReviewObject.source = "google"
		do reviewArray.$push(newReviewObject)
	}
	
	//4. Get website reviews and place as-is into reviewArray
	set websiteCollection = db.$getCollection("websitereviews")
	set i= websiteCollection.$getIterator()
	while i.$getNext(.key,.value) {
		set value = websiteCollection.$get(key)
		set newReviewObject = value
		do reviewArray.$push(newReviewObject)
	}

	//5. Return array of reviews
	set jsonString = reviewArray.$toJSON()
	quit jsonString
]]></Implementation>
</Method>

<Method name="%OnAfterCreatePage">
<Description><![CDATA[
This callback is called after the server-side page 
object and all of its children are created.<br/>
Subclasses can override this to add, remove, or modify 
items within the page object model, or to provide values
for controls.
PURPOSE: Pull reviews from Google and put into docDB as is]]></Description>
<ReturnType>%Status</ReturnType>
<Implementation><![CDATA[
	try {
		set r = ##class(%Net.HttpRequest).%New()
		set r.Server="maps.googleapis.com"
		set r.Https = 1
		set r.SSLConfiguration="Connect to Google API"
		set r.Timeout = 15
		set st = r.Get("/maps/api/place/details/json?placeid=ChIJN1t_tDeuEmsRUsoyG83frY4&key=AIzaSyD6ofgUDUUilDPsqQ0eVeh69sjPL1P0MvY&format=1")
		//set st = ##class(%ZEN.Auxiliary.jsonProvider).%ConvertJSONToObject(r.HttpResponse.Data, , .obj) 
			
		//Open reviews document database collection
		set db = ##class(%DataModel.Document.Database).$getDatabase()
		do db.$dropCollection("googlereviews")
		set collection = db.$getCollection("googlereviews")
		
		//Create dynamic object and strip out extra information that is not review data
		set place = ##class(%AbstractObject).$fromJSON(r.HttpResponse.Data)
		set reviewsArray= place.result.reviews

		//Convert to JSON string and replace first document with 
		do collection.$insertArray(reviewsArray)
	}
	catch {
		//Set noteText = "NOTE: Cannot connect to Google. Using old data."
		&js<zen('noteText').setValue('NOTE: Connect connect to Google. Using old data.'); zen('noteText').setProperty('Hidden',"False");>
		
	}
	
	Quit $$$OK
]]></Implementation>
</Method>
</Class>


<Class name="Restaurant.Reviews">
<Super>%Persistent</Super>
<TimeChanged>64034,55424.247998</TimeChanged>
<TimeCreated>64004,76423.062678</TimeCreated>

<Property name="reviewer">
<Type>%String</Type>
</Property>

<Property name="review">
<Type>%String</Type>
</Property>

<Property name="source">
<Type>%String</Type>
</Property>

<Property name="timestamp">
<Type>%DateTime</Type>
</Property>

<Property name="rating">
<Type>%String</Type>
<Parameter name="VALUELIST" value=",Excellent,Good,Average,Poor,Terrible"/>
</Property>

<Storage name="Default">
<Type>%Library.CacheStorage</Type>
<DataLocation>^Restaurant.ReviewsD</DataLocation>
<DefaultData>ReviewsDefaultData</DefaultData>
<IdLocation>^Restaurant.ReviewsD</IdLocation>
<IndexLocation>^Restaurant.ReviewsI</IndexLocation>
<StreamLocation>^Restaurant.ReviewsS</StreamLocation>
<Data name="ReviewsDefaultData">
<Value name="1">
<Value>%%CLASSNAME</Value>
</Value>
<Value name="2">
<Value>reviewer</Value>
</Value>
<Value name="3">
<Value>review</Value>
</Value>
<Value name="4">
<Value>source</Value>
</Value>
<Value name="5">
<Value>timestamp</Value>
</Value>
<Value name="6">
<Value>rating</Value>
</Value>
</Data>
</Storage>
</Class>
</Export>
