text:
2015. Ronneby Wordpress Theme.
Audio previews from past film and game soundtracks
INDUSTRY RECOGNITIONS
FEATURED SCORES
IN THE MIND'S EYE
Dir. Kellen Gibbs, Prod. Rochel Goldsmith,
Arn Andersson, Walid Feghali
Gifted with the ability to extract and inhabit other people's memories, Greer Thompson is an example of how incredible powers come at a price. She isolates herself and tries to live a very simple life but when she is confronted by a man who has been affected by her abilities, she is forced to question her own reality.
SOUNDTRACK PREVIEW
THE MOMENT I WAS ALONE
Dir. Kellen Gibbs, Prod. Rochel Goldsmith
Quinn is a young girl, living in the shadow of a workaholic mother. Rushing to school one day, the world around Quinn freezes in time. She is completely alone. What at first seems to her a blessing and a game, soon turns bitter and isolating. Unable to communicate with anyone or anything around her, Quinn must survive on her own in a world where she is the only thing affected by time.
TOM CLANCY'S SHADOWBREAK
Developed by Ubisoft Halifax
Lead the ShadowBreak squad as an elite sniper and battle players in real time PvP sniper combat. You are the tactical commander of a ShadowBreak squad comprised of military specialists from around the world and trained in unorthodox warfare and counter-insurgency. A Ubisoft Toronto-Halifax collaboration. Co-composed with Spencer Creaghan and mixed by Mike Peters.
Dir. Nils Taylor, Prod. Nicole Marie Johnson
As a group of women embark on a hiking expedition, they become brazenly stalked by a pack of predators, leading to a physical and emotional cat-and-mouse chase with an outcome neither expected. Quarries is the all new, award-winning independent film from the Producer of Final Destination.
DREAM REVENANT
iOS Mobile Game by George Lippert
Dream Revenant pushes the limits of both graphical immersion and narrative intensity, incorporating a fully explorable, fully living world rich with dark secrets and hidden memories. Coming soon for iOS and Android, powered by Unreal, created by Speedbump Games and BulkyPix.
Canadian-Argentine composer Isaias Garcia is a 2-time Hollywood Music in Media Award winner and 9-time nominee, and 4-time SOCAN Foundation Audio/Visual Awards recipient, having worked on a wide range of mainstream and independent projects for film, video games, and the concert hall. Born in Canada and raised in Argentina, he had a humble and grounded musical upbringing in both countries, absorbing the works of the unique filmmakers and composers from Buenos Aires and Hollywood alike. At age 17, he became the youngest-ever composer-in-residence of Toronto's Celebrity Symphony Orchestra, and later served as its orchestra manager during his music studies at York University's School of the Arts, Media, Performance, and Design. In 2013, Isaias was invited as a guest student at USC's Thornton School of Music's film scoring program with industry-renowned composers Garry Schyman and John Debney, which coincided with his 3rd Hollywood Music in Media Award nomination in the mobile game category, competing with Ubisoft's Assassin's Creed III. Isaias would later score the 2017 Ubisoft video game, Tom Clancy's ShadowBreak, making him one of the youngest composers to join the ranks of the highly acclaimed artists who have lent their talents to the Tom Clancy action video game franchise. Isaias has worked on over 30 professional projects, frequently working with his long-time collaborator, director Kellen Gibbs (The Moment I Was Alone, In The Mind's Eye); and director Nils Taylor and producer Nicole Marie-Johnson (Quarries). He currently resides in Toronto and will be scoring the 2020 feature film, The Freezing Season.
PROFESSIONAL INQUIRIES
© 2019 Isaias Garcia | All Rights Reserved | Designed by I&J Designs


Our beautiful girls Christmas dress brings Old Saint Nick "aka" Santa Claus hand smocked around the neckline along with a snowman and a Christmas tree. Your little baby girl will love the patriotic Santa in this Christmas dress because she knows Father Christmas is bringing gifts to the homes of well-behaved, good children on Christmas Eve. This joyful dress is made in red micro gingham poly-cotton fabric, very soft and easy to care, easy to iron if needed. The short sleeves are also gently smocked to add a fine detail. Coordinated brother and sister outfits are available for those special Family Christmas Pictures.


text:
<!DOCTYPE html>

    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <title>Authentication Example : revIgniter User Guide</title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta name="robots" content="all">
    <meta name="author" content="Ralf Bitter" >
    <meta name="description" content="revIgniter User Guide">

    <link rel="stylesheet" media="screen" href="../../css/style-ck.css">

    <link rel="apple-touch-icon-precomposed" sizes="144x144" href="../../images/apple-touch-icon-144-precomposed.png">
    <link rel="apple-touch-icon-precomposed" sizes="114x114" href="../../images/apple-touch-icon-114-precomposed.png">
    <link rel="apple-touch-icon-precomposed" sizes="72x72" href="../../images/apple-touch-icon-72-precomposed.png">
    <link rel="apple-touch-icon-precomposed" href="../../images/apple-touch-icon-57-precomposed.png">

          <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">

          </button>
          revIgniter User Guide Version 2.3.3

          <form class="navbar-form navbar-right" role="search" method="get" action="https://duckduckgo.com/">

 				<input type="hidden" name="sites" value="revigniter.com/userGuide/"/>
				<input type="hidden" name="kj" value="#000000"/>
				<input type="hidden" name="k7" value="#2B3137"/>
				<input type="hidden" name="k8" value="#C7C7C7"/>
			  <input type="hidden" name="k9" value="#85EAFB"/>
				<input type="hidden" name="kx" value="#FFFFFF"/>
				<input type="hidden" name="kaa" value="#FFFFFF"/>
				<input type="hidden" name="kaa" value="#FFFFFF"/>
			  <input type="hidden" name="k1" value="-1"/>
 		        Search User Guide   <input type="search" placeholder="Search…" name="q" id="q" class="revignitersearch" maxlength="255" />
 				 <input type="image" id="submitSearch" src="../../images/searchGo.png" />

 		 	 		</form>

revIgniter Home

User Guide Home

Authentication

Example

Table of Contents Page

Table of Contents

Close

Usage Example

Before explaining what is needed to set up the authentication sample, let's describe the scenario:

There is an admin page which is used to manage user data (example.com/auth/).

Opening this page without being logged in as a member of the admin group redirects you to a login page (example.com/auth/login/).

A form is displayed on this page requiring you to fill in your credentials.

Now if you submit something invalid, the form is redisplayed containing an error message describing the problem.

If the verification of the data you supply is successful you will be redirected either to a member's page or to the admin page mentioned earlier, depending on which group you belong to.

Then, let's say you forgot your password.

Open the "Forgot Password" page, enter your email address and hit the send button (example.com/auth/forgotPassword/).

Now, while you are redirected to the login page there is an email waiting for you containing a link to a "Reset Password" page (example.com/auth/resetPassword/).

On this page enter a new password, confirm it and hit the submit button.

You are redirected to the login page where you can enter your new password.

To change your password open the "Change Password" page (example.com/auth/changePassword/), enter your email address and your password. Hit the submit button.

The procedure which follows is similar to the forgotten password one.

Now, let's say you logged in as a member of the admin group.

You will be presented with the administration page (example.com/auth/).

There you can create new users, activate / deactivate, edit and delete users.

The sample environment consists of the following files:

A controller to receive and process the submitted data.

A form validation file.

Various view files containing forms or a users table.

A CSS file.

Let's create those files.

The Controller

The Form Validation File

The View Files

The CSS File

The Controller

We start with the basic authentication controller script containing just the handler to load helpers respectively libraries and the default (index) handler. Create a controller called auth.lc. In it, place the code below and save it to your application/controllers/ folder.

<?lc

put "auth,index,login,logout,createUser,activate,deactivate,forgotPassword" & \
",resetPassword,changePassword,editUser,deleteUser" into gControllerHandlers

command auth
 # LOAD HELPERS
 put "form,url,asset" into tHelpers
 rigLoadHelper tHelpers

 # LOAD LIBRARIES
 rigLoaderLoadLibrary "Formvalidation"
 rigLoaderLoadLibrary "Table"
 rigLoaderLoadLibrary "Authentication"
end auth

command index
 # SET PAGE TITLE
 put "Auth Test Admin Page" into gData["pageTitle"]

 # CHECK IF USER IS LOGGED IN
 if rigAuthLoggedIn() is FALSE then
  # REDIRECT TO LOGIN PAGE AND KEEP FLASHDATA IN CASE THERE IS ANY
  if rigSessFlashdata("message") <> FALSE then
   rigKeepSessFlashdata "message"
  end if

  rigRedirect "auth/login"

 else if rigAuthIsAdmin() is FALSE then
  # REDIRECT TO HOME PAGE BECAUSE USER IS NOT ALLOWED TO VIEW ADMIN CONTENT
  rigRedirect "/"

 else
  # ADMIN CONTENT
  #
  # SHOW VALIDATION ERRORS OR FLASH DATA IN CASE THERE IS ANY
  put rigValidationErrors("<div class=" & quote & "error" & quote & ">", "</div>") into tErrors
  if tErrors <> empty then
   put tErrors into gData["message"]
  else
   put rigSessFlashdata("message") into gData["message"]
   if gData["message"] is FALSE then
    put empty into gData["message"]
   end if
  end if

  # BUILD USERS LIST
  put rigAuthUsers() into tResult -- gData["users"]

  if tResult <> FALSE then

   # BUILD MODIFIED RESULT ARRAY
   put 0 into tIncr
   repeat for each key tKey in tResult
    add 1 to tIncr

    put tResult[tIncr] into tRow
    # GET FIRST, LAST NAME AND EMAIL
    put tRow[13] into tResultData[tIncr][1]
    put tRow[14] into tResultData[tIncr][2]
    put tRow[5] into tResultData[tIncr][3]

    # GET USERS GROUPS
    put rigAuthUserGroups(tRow[1]) into tGroupsResult

    if tGroupsResult <> FALSE then
     repeat for each key tKey in tGroupsResult
      put tGroupsResult[tKey] into tGroupsRow
      # GET NAME OF GROUP
      put tGroupsRow[2] & ", " after tResultData[tIncr][4]
     end repeat
     delete char -2 to -1 of tResultData[tIncr][4]
    end if

    # GET STATUS
    if tRow[12] is 1 then
     put rigAnchor("auth/deactivate/" & tRow[1], "Active") into tResultData[tIncr][5]
    else
     put rigAnchor("auth/activate/" & tRow[1], "Inactive") into tResultData[tIncr][5]
    end if

    # LINK TO EDIT USER
    put rigAnchor("auth/editUser/" & tRow[1], "Edit") into tResultData[tIncr][6]

    # LINK TO DELETE USER
    put rigAnchor("auth/deleteUser/" & tRow[1], "Delete") into tResultData[tIncr][7]
   end repeat

   # NOW GENERATE A USERS TABLE
   put "First Name", "Last Name", "Email", "Groups", "Status", "Edit, Delete" into tFieldnames
   rigSetTableHeading tFieldnames
   put rigGenerateTable(tResultData) into gData["usersTable"]
  end if

  # LINK TO LOGOUT
  put rigAnchor("auth/logout/", "Logout") into gData["logoutLink"]

  # LINK TO CREATE NEW USER
  put rigAnchor("auth/createUser/", "Create New User.") into gData["newUserLink"]

  # LOAD THE VIEW FILE
  get rigLoadView("auth/authMainView")
 end if
end index

Top of Page

Add the following code which is needed to create new user data.

command createUser
 put "Auth Test Create User" into gData["pageTitle"]

 # CHECK IF USER IS NOT LOGGED IN OR IF USER IS NOT ADMIN
 if (rigAuthLoggedIn() is not TRUE) or (rigAuthIsAdmin() is not TRUE) then
  # REDIRECT TO ADMIN (LOGIN) PAGE
  rigRedirect "auth/"
 end if

 # FORM OPEN
 put "authForm" into tFormAttr["id"]
 put rigFormOpen("auth/createUser", tFormAttr) into gData["formOpen"]

 # FIELD SET
 put rigFormFieldset("User Data") into gData["fsOpen"]
 put rigFormFieldsetClose() into gData["fsClose"]

 # FORM LABELS
 put "formLabel" into tLabelAttr["class"]
 put rigFormLabel("First Name:", "first", tLabelAttr) into gData["firstLabel"]
 put rigFormLabel("Last Name:", "last", tLabelAttr) into gData["lastLabel"]
 put rigFormLabel("Company:", "company", tLabelAttr) into gData["companyLabel"]
 put rigFormLabel("Email:", "email", tLabelAttr) into gData["emailLabel"]
 put rigFormLabel("Phone:", "phone", tLabelAttr) into gData["phoneLabel"]
 put rigFormLabel("Password:", "password", tLabelAttr) into gData["passwordLabel"]
 put rigFormLabel("Confirm Password:", "passwordConfirm", tLabelAttr) into gData["passwordConfirmLabel"]

 # SUBMIT
 put "createSubmit" into tSubmitArr["name"]
 put "Create User" into tSubmitArr["value"]
 put "createBtn" into tSubmitArr["id"]
 put rigSubmitButton(tSubmitArr) into gData["createSubmit"]

 # FORM VALIDATION
 if rigFormValidRun("auth/createUser") is TRUE then
  # GET ACCOUNT DATA
  if $_POST is an array then
   put toLower(rigVarPOST("first")) && toLower(rigVarPOST("last")) into tUserName
   put rigVarPOST("password") into tPassword
   put rigVarPOST("email") into tEmail

   put rigVarPOST("first") into tExtraData["firstName"]
   put rigVarPOST("last") into tExtraData["lastName"]
   put rigVarPOST("company") into tExtraData["company"]
   put rigVarPOST("phone") into tExtraData["phone"]
  end if

  put rigAuthRegister(tUserName, tPassword, tEmail, tExtraData) into tRegistration

  # CHECK REGISTRATION DATA
  if tRegistration is an array then
   rigLogMessage "debug", "identity:" && tRegistration["identity"]
   rigLogMessage "debug", "id:" && tRegistration["id"]
   rigLogMessage "debug", "email:" && tRegistration["email"]
   rigLogMessage "debug", "activationCode:" && tRegistration["activationCode"]
  else
   rigLogMessage "debug", "tRegistration:" && tRegistration
  end if
  rigLogMessage "debug", "messages:" && rigAuthMessages()
  #

  # IF REGISTRATION WAS SUCCESSFUL REDIRECT TO AUTHENTICATION PAGE
  if tRegistration <> FALSE then
   put rigAuthMessages() into tMessages
   rigSetSessFlashdata "message", tMessages
   rigRedirect "/auth"
  else
   # LOAD VIEW
   put rigAuthErrors() into tErrors
   rigSetSessFlashdata "message", tErrors
   rigRedirect "auth/createUser"
  end if

 else -- if rigFormValidRun("auth/createUser") is TRUE then

  put rigValidationErrors("<div class=" & quote & "error" & quote & ">", "</div>") into tErrors
  if tErrors <> empty then
   put tErrors into gData["message"]
  else
   put rigSessFlashdata("message") into gData["message"]
   if gData["message"] is FALSE then
    put empty into gData["message"]
   end if
  end if

  # INPUT FIELDS
  put "first" into tInFirstArr["name"]
  # RE-POPULATE THE FIELD
  put rigSetValue("first") into tInFirstArr["value"]
  put "50" into tInFirstArr["maxlength"]
  put rigFormInput(tInFirstArr) into gData["first"]

  put "last" into tInLastArr["name"]
  # RE-POPULATE THE FIELD
  put rigSetValue("last") into tInLastArr["value"]
  put "50" into tInLastArr["maxlength"]
  put rigFormInput(tInLastArr) into gData["last"]

  put "company" into tInCompArr["name"]
  # RE-POPULATE THE FIELD
  put rigSetValue("company") into tInCompArr["value"]
  put "100" into tInCompArr["maxlength"]
  put rigFormInput(tInCompArr) into gData["company"]

  put "email" into tInMailArr["name"]
  # RE-POPULATE THE FIELD
  put rigSetValue("email") into tInMailArr["value"]
  put "50" into tInMailArr["maxlength"]
  put rigFormInput(tInMailArr) into gData["email"]

  put "phone" into tInPhoneArr["name"]
  # RE-POPULATE THE FIELD
  put rigSetValue("phone") into tInPhoneArr["value"]
  put "50" into tInPhoneArr["maxlength"]
  put rigFormInput(tInPhoneArr) into gData["phone"]

  put "password" into tInPassArr["name"]
  # RE-POPULATE THE FIELD
  put rigSetValue("password") into tInPassArr["value"]
  put "50" into tInPassArr["maxlength"]
  put rigFormInput(tInPassArr) into gData["password"]

  put "passwordConfirm" into tInPassConfArr["name"]
  # RE-POPULATE THE FIELD
  put rigSetValue("passwordConfirm") into tInPassConfArr["value"]
  put "50" into tInPassConfArr["maxlength"]
  put rigFormInput(tInPassConfArr) into gData["passwordConfirm"]
 end if

 # LOAD VIEW
 get rigLoadView("auth/createUserMainView")
end createUser

Top of Page

Add the login handler.

command login
 put "Auth Test Login" into gData["pageTitle"]

 # FORM OPEN
 put "authForm" into tFormAttr["id"]
 put rigFormOpen("auth/login", tFormAttr) into gData["formOpen"]

 # FIELD SET
 put rigFormFieldset("Login Form") into gData["fsOpen"]
 put rigFormFieldsetClose() into gData["fsClose"]

 # FORM LABELS
 put "formLabel" into tLabelAttr["class"]
 put rigFormLabel("Email/Username:", "identity", tLabelAttr) into gData["identityLabel"]
 put rigFormLabel("Password:", "password", tLabelAttr) into gData["passwordLabel"]
 put rigFormLabel("Remember me:", "remember", tLabelAttr) into gData["rememberLabel"]

 # SUBMIT
 put "loginSubmit" into tSubmitArr["name"]
 put "Login" into tSubmitArr["value"]
 put "loginBtn" into tSubmitArr["id"]
 put rigSubmitButton(tSubmitArr) into gData["loginSubmit"]

 # FORM VALIDATION
 if rigFormValidRun("auth/login") is TRUE then

  # CHECK IF USER IS LOGGING IN
  # REMEMBER ME CHECK BOX
  put FALSE into tRemember
  # CHECK IF THERE IS A POST VARIABLE remember
  put rigVarPost("remember[]") into tPostRemember
  if tPostRemember <> FALSE then
   # CHECK VALUE
   if tPostRemember[1] is 1 then
    put TRUE into tRemember
   end if
  end if

  get rigAuthLogin(rigVarPost("identity"), rigVarPost("password"), tRemember)

  # IF LOGIN IS SUCCESSFUL REDIRECT BACK TO HOME PAGE, auth IN THIS CASE
  if it is TRUE then
   put rigAuthMessages() into tMessages
   rigSetSessFlashdata "message", tMessages
   rigRedirect "/auth"

  else
   # IF LOGIN IS UNSUCCESSFUL REDIRECT BACK TO THE LOGIN PAGE
   put rigAuthErrors() into tErrors
   rigSetSessFlashdata "message", tErrors
   rigRedirect "auth/login"
  end if

 else
  # THE USER IS NOT LOGGING IN, SHOW THE LOGIN PAGE
  # SHOW VALIDATION ERRORS OR FLASH DATA IF THERE IS ANY
  put rigValidationErrors("<div class=" & quote & "error" & quote & ">", "</div>") into tErrors
  if tErrors <> empty then
   put tErrors into gData["message"]
  else
   put rigSessFlashdata("message") into gData["message"]
   if gData["message"] is FALSE then
    put empty into gData["message"]
   end if
  end if

  # INPUT FIELDS
  put "identity" into tInIdentArr["name"]
  # RE-POPULATE THE FIELD
  put rigSetValue("identity") into tInIdentArr["value"]
  put "100" into tInIdentArr["maxlength"]
  put rigFormInput(tInIdentArr) into gData["identity"]

  put "password" into tInPwArr["name"]
  put "40" into tInPwArr["maxlength"]
  put rigFormInput(tInPwArr) into gData["loginPassword"]

  # CHECKBOX
  put rigSetCheckbox("remember[]", "1", TRUE) into gData["chbRemember"]

  get rigLoadView("auth/loginMainView")

 end if -- if rigFormValidRun("auth/login") is TRUE then
end login

Top of Page

Of course there is a logout handler.

command logout
 # LOG USER OUT
 rigAuthLogout

 # REDIRECT TO THE LOGIN PAGE
 put rigAuthMessages() into tMessages

 rigSetSessFlashdata "message", tMessages
 rigRedirect "/auth/login"
end logout

Top of Page

Add the following user activation handler.

command activate
 # GET USER ID AND ACTIVATION CODE
 put rigFetchSegment(3) into tID
 put rigFetchSegment(4) into tCode
 put FALSE into tActivation

 # ACTIVATE USER
 if tCode <> FALSE then
  put rigAuthActivate(tID, tCode) into tActivation

 else if rigAuthIsAdmin() is TRUE then
  put rigAuthActivate(tID) into tActivation
 end if

 # CHECK IF ACTIVATION WAS SUCCESSFUL AND ACT ACCORDINGLY
 if tActivation is TRUE then
  # REDIRECT TO THE AUTH PAGE
  put rigAuthMessages() into tMessages

  rigSetSessFlashdata "message", tMessages
  rigRedirect "/auth"

 else
  put rigAuthErrors() into tErrors

  rigSetSessFlashdata "message", tErrors
  rigRedirect "auth/forgotPassword"
 end if
end activate

Top of Page

Add the user deactivation handler.

command deactivate
 put "Auth Test Deactivate" into gData["pageTitle"]

 put rigFetchSegment(3) into tID

 # FORM OPEN
 put "authForm" into tFormAttr["id"]
 put rigFormOpen("auth/deactivate/" & tID, tFormAttr) into gData["formOpen"]

 # FIELD SET
 put rigFormFieldset("Deactivate User Form") into gData["fsOpen"]
 put rigFormFieldsetClose() into gData["fsClose"]

 # FORM LABELS
 put "formLabel" into tLabelAttr["class"]
 put rigFormLabel("Yes:", "confirm", tLabelAttr) into gData["confirmRadioYesLabel"]
 put rigFormLabel("No:", "confirm", tLabelAttr) into gData["confirmRadioNoLabel"]

 # SUBMIT
 put "deactivateSubmit" into tSubmitArr["name"]
 put "Submit" into tSubmitArr["value"]
 put "submitBtn" into tSubmitArr["id"]
 put rigSubmitButton(tSubmitArr) into gData["deactivateSubmit"]

 # FORM VALIDATION
 if rigFormValidRun("auth/deactivate") is TRUE then
  put FALSE into tDeactivated

  # CHECK IF DEACTIVATION WAS CONFIRMED
  if rigVarPOST("confirm") is "yes" then

   # VALIDATE THE REQUEST
   if tID <> rigVarPOST("id") then
    rigLogMessage "error", "This user deactivation form post did not pass the security check.", TRUE
   end if

   # CHECK THE USER LEVEL
   if (rigAuthLoggedIn() is TRUE) and (rigAuthIsAdmin() is TRUE) then
    put rigAuthDeactivate(tID) into tDeactivated
   end if

  end if

  # GET AUTH MESSAGES AND REDIRECT TO THE AUTH PAGE
  if tDeactivated is TRUE then
   put rigAuthMessages() into tMessages
  else
   put rigAuthErrors() into tMessages
  end if

  rigSetSessFlashdata "message", tMessages
  rigRedirect "/auth"

 else
  put rigValidationErrors("<div class=" & quote & "error" & quote & ">", "</div>") into tErrors
  if tErrors <> empty then
   put tErrors into gData["message"]
  else
   put rigSessFlashdata("message") into gData["message"]
   if gData["message"] is FALSE then
    put empty into gData["message"]
   end if
  end if

  # HIDDEN USER ID FIELD
  put rigAuthUser(tID) into tQueryResult
  if (tQueryResult <> FALSE) and (tQueryResult is an array) then
   put rigDbRow() into tUserRow
   put tUserRow["id"] into tUserID
   put tUserRow["username"] into gData["userName"]
  else
   put empty into tUserID
  end if
  put rigFormHidden("id", tUserID) into gData["hiddenUserID"]

  # RADIO BUTTONS
  put rigSetRadio("confirm", "yes") into gData["confirmYes"]
  put rigSetRadio("confirm", "no", TRUE) into gData["confirmNo"]

  # LOAD VIEWS
  get rigLoadView("auth/deactivateUserMainView")
 end if
end deactivate

Top of Page

Add the "forgotPassword" handler.

command forgotPassword
 put "Auth Test Forgot Password" into gData["pageTitle"]

 put rigSessFlashdata("message") into gData["message"]

 # FORM OPEN
 put "authForm" into tFormAttr["id"]
 put rigFormOpen("auth/forgotPassword/", tFormAttr) into gData["formOpen"]

 # FIELD SET
 put rigFormFieldset("Forgot Password Form") into gData["fsOpen"]
 put rigFormFieldsetClose() into gData["fsClose"]

 # FORM LABELS
 put "formLabel" into tLabelAttr["class"]
 put rigFormLabel("Email:", "email", tLabelAttr) into gData["emailLabel"]

 # SUBMIT
 put "forgotSubmit" into tSubmitArr["name"]
 put "Submit" into tSubmitArr["value"]
 put "forgotBtn" into tSubmitArr["id"]
 put rigSubmitButton(tSubmitArr) into gData["forgotSubmit"]

 # FORM VALIDATION
 if rigFormValidRun("auth/forgotPassword") is TRUE then
  # CALL THE rigAuthForgottenPassword FUNCTION TO SEND A RESET CODE TO THE USER
  put rigAuthForgottenPassword(rigVarPOST("email")) into tResetPasswordSent

  if tResetPasswordSent is TRUE then
   put rigAuthMessages() into tMessages

   rigSetSessFlashdata "message", tMessages
   rigRedirect "/auth/login"
  else
   put rigAuthErrors() into tErrors

   rigSetSessFlashdata "message", tErrors
   rigRedirect "auth/forgotPassword"
  end if

 else
  put rigValidationErrors("<div class=" & quote & "error" & quote & ">", "</div>") into tErrors
  if tErrors <> empty then
   put tErrors into gData["message"]
  else
   put rigSessFlashdata("message") into gData["message"]
   if gData["message"] is FALSE then
    put empty into gData["message"]
   end if
  end if

  # INPUT FIELDS
  put "email" into tInMailArr["name"]
  # RE-POPULATE THE FIELD
  put rigSetValue("email") into tInMailArr["value"]
  put "50" into tInMailArr["maxlength"]
  put rigFormInput(tInMailArr) into gData["email"]
 end if

 # LOAD VIEW
 get rigLoadView("auth/forgotPasswordMainView")
end forgotPassword

Top of Page

Add code which is used to reset passwords in case a user forgot the password or sent a change password request.

command resetPassword
 put "Auth Test Reset Password" into gData["pageTitle"]

 put rigFetchSegment(3) into tForgottenPasswordCode

 if tForgottenPasswordCode is FALSE then
  rigShow404
 end if

 put rigAuthForgottenPasswordCheck(tForgottenPasswordCode) into tUser

 if tUser <> FALSE then
  put rigAuthFetchConfigItem("minLengthPassword") into tMinPasswordLength
  put rigAuthFetchConfigItem("maxLengthPassword") into tMaxPasswordLength

  # FORM OPEN
  put "authForm" into tFormAttr["id"]
  put rigFormOpen("auth/resetPassword/" & tForgottenPasswordCode, tFormAttr) into gData["formOpen"]

  # FIELD SET
  put rigFormFieldset("Reset Password Form") into gData["fsOpen"]
  put rigFormFieldsetClose() into gData["fsClose"]

  # FORM LABELS
  put "formLabel" into tLabelAttr["class"]
  put rigFormLabel("New Password (at least" && tMinPasswordLength && "characters long):", \
"newPassword", tLabelAttr) into gData["newPasswordLabel"]
  put rigFormLabel("Confirm New Password:", "newPasswordConfirm", tLabelAttr) into gData["newPasswordConfirmLabel"]

  # SUBMIT
  put "resetSubmit" into tSubmitArr["name"]
  put "Change" into tSubmitArr["value"]
  put "resetBtn" into tSubmitArr["id"]
  put rigSubmitButton(tSubmitArr) into gData["resetSubmit"]

  # IF THE CODE IS VALID DISPLAY THE PASSWORD RESET FORM
  # FORM VALIDATION
  if rigFormValidRun("auth/resetPassword") is TRUE then

   # VALIDATE THE REQUEST
   if tUser["id"] <> rigVarPOST("hiddenUserID") then
    get rigAuthClearForgottenPasswordCode(tForgottenPasswordCode)
    rigLogMessage "error", "This reset password form post did not pass the security check.", TRUE

   else
    # CHANGE THE PASSWORD
    put rigAuthFetchConfigItem("identityColumn") into tIdentityCol
    put tUser[tIdentityCol] into tIdentity

    put rigAuthResetPassword(tIdentity, rigVarPOST("newPassword")) into tChange

    if tChange is TRUE then
     # THE PASSWORD WAS SUCCESSFULLY CHANGED
     put rigAuthMessages() into tMessages

     rigSetSessFlashdata "message", tMessages
     logout

    else
     put rigAuthErrors() into tErrors

     rigSetSessFlashdata "message", tErrors
     rigRedirect "auth/resetPassword/" & tForgottenPasswordCode
    end if

   end if

  else
   # DISPLAY THE FORM
   # SET THE FLASH DATA ERROR MESSAGE IF THERE IS ONE
   put rigValidationErrors("<div class=" & quote & "error" & quote & ">", "</div>") into tErrors
   if tErrors <> empty then
    put tErrors into gData["message"]
   else
    put rigSessFlashdata("message") into gData["message"]
    if gData["message"] is FALSE then
     put empty into gData["message"]
    end if
   end if

   # INPUT FIELDS
   put "newPassword" into tInPassArr["name"]
   put tMaxPasswordLength into tInPassArr["maxlength"]
   put "password" into tInPassArr["type"]
   put rigFormInput(tInPassArr) into gData["newPassword"]

   put "newPasswordConfirm" into tInPassConfArr["name"]
   put tMaxPasswordLength into tInPassConfArr["maxlength"]
   put "password" into tInPassConfArr["type"]
   put rigFormInput(tInPassConfArr) into gData["newPasswordConfirm"]

   put "hiddenUserID" into tInUserIdArr["name"]
   put tUser["id"] into tInUserIdArr["value"]
   put "hidden" into tInUserIdArr["type"]
   put rigFormInput(tInUserIdArr) into gData["hiddenUserID"]

   # LOAD VIEW
   get rigLoadView("auth/resetPasswordMainView")

  end if -- if rigFormValidRun("auth/forgotPassword") is TRUE then

 else  -- if tUser <> FALSE then
  put rigAuthErrors() into tErrors

  rigSetSessFlashdata "message", tErrors
  rigRedirect "auth/forgotPassword"
 end if -- if tUser <> FALSE then

end resetPassword

Top of Page

Add a handler which is used to change passwords.

command changePassword
 put "Auth Test Change Password" into gData["pageTitle"]

 # CHECK IF USER IS LOGGED IN
 if rigAuthLoggedIn() is FALSE then
  rigRedirect "/auth/login"
 end if

 # GET USER DATA
 put rigAuthUser() into tQueryResult

 if (tQueryResult <> FALSE) and (tQueryResult is an array) then
  put rigDbRow() into tUser
 end if

 # GET MIN / MAX PASSWORD LENGTH
 put rigAuthFetchConfigItem("minLengthPassword") into tMinPasswordLength
 put rigAuthFetchConfigItem("maxLengthPassword") into tMaxPasswordLength

 # FORM OPEN
 put "authForm" into tFormAttr["id"]
 put rigFormOpen("auth/changePassword/", tFormAttr) into gData["formOpen"]

 # FIELD SET
 put rigFormFieldset("Change Password Form") into gData["fsOpen"]
 put rigFormFieldsetClose() into gData["fsClose"]

 # FORM LABELS
 put "formLabel" into tLabelAttr["class"]
 put rigFormLabel("Old Password:", "oldPassword", tLabelAttr) into gData["oldPasswordLabel"]
 put rigFormLabel("New Password (at least" && tMinPasswordLength && "characters long):", \
"newPassword", tLabelAttr) into gData["newPasswordLabel"]
 put rigFormLabel("Confirm New Password:", "newPasswordConfirm", tLabelAttr) into gData["newPasswordConfirmLabel"]

 # SUBMIT
 put "changeSubmit" into tSubmitArr["name"]
 put "Change" into tSubmitArr["value"]
 put "changeBtn" into tSubmitArr["id"]
 put rigSubmitButton(tSubmitArr) into gData["changeSubmit"]

 # FORM VALIDATION
 if rigFormValidRun("auth/changePassword") is TRUE then
  put rigAuthFetchConfigItem("identityColumn") into tIdentityCol
  put rigSessUserdata(tIdentityCol) into tIdentity

  put rigAuthChangePassword(tIdentity, rigVarPOST("oldPassword"), rigVarPOST("newPassword")) into tChange

  if tChange is TRUE then
   # THE PASSWORD WAS SUCCESSFULLY CHANGED
   put rigAuthMessages() into tMessages

   rigSetSessFlashdata "message", tMessages
   logout

  else
   put rigAuthErrors() into tErrors

   rigSetSessFlashdata "message", tErrors
   rigRedirect "auth/changePassword/" & tForgottenPasswordCode
  end if

 else
  # DISPLAY THE FORM
  # SET THE FLASH DATA ERROR MESSAGE IF THERE IS ONE
  put rigValidationErrors("<div class=" & quote & "error" & quote & ">", "</div>") into tErrors
  if tErrors <> empty then
   put tErrors into gData["message"]
  else
   put rigSessFlashdata("message") into gData["message"]
   if gData["message"] is FALSE then
    put empty into gData["message"]
   end if
  end if

  # INPUT FIELDS
  put "oldPassword" into tInOldPassArr["name"]
  put tMaxPasswordLength into tInOldPassArr["maxlength"]
  put "password" into tInOldPassArr["type"]
  put rigFormInput(tInOldPassArr) into gData["oldPassword"]

  put "newPassword" into tInPassArr["name"]
  put tMaxPasswordLength into tInPassArr["maxlength"]
  put "password" into tInPassArr["type"]
  put rigFormInput(tInPassArr) into gData["newPassword"]

  put "newPasswordConfirm" into tInPassConfArr["name"]
  put tMaxPasswordLength into tInPassConfArr["maxlength"]
  put "password" into tInPassConfArr["type"]
  put rigFormInput(tInPassConfArr) into gData["newPasswordConfirm"]

  put "hiddenUserID" into tInUserIdArr["name"]
  put tUser["id"] into tInUserIdArr["value"]
  put "hidden" into tInUserIdArr["type"]
  put rigFormInput(tInUserIdArr) into gData["hiddenUserID"]

  # LOAD VIEW
  get rigLoadView("auth/changePasswordMainView")

 end if -- if rigFormValidRun("auth/resetPassword") is TRUE then
end changePassword

Top of Page

Add a handler which is used to edit user data.

command editUser
 put "Auth Test Edit User" into gData["pageTitle"]

 # CHECK IF USER IS NOT LOGGED IN OR IF USER IS NOT ADMIN
 if (rigAuthLoggedIn() is not TRUE) or (rigAuthIsAdmin() is not TRUE) then
  # REDIRECT TO AUTH PAGE
  rigRedirect "auth/"
 end if

 # GET MIN / MAX PASSWORD LENGTH
 put rigAuthFetchConfigItem("minLengthPassword") into tMinPasswordLength
 put rigAuthFetchConfigItem("maxLengthPassword") into tMaxPasswordLength

 # GET USER ID
 put rigFetchSegment(3) into tID

 # GET STORED USER DATA
 put rigAuthUser(tID) into tQueryResult
 if (tQueryResult <> FALSE) and (tQueryResult is an array) then
  put rigDbRow() into tUser
 end if

 # FORM OPEN
 put "authForm" into tFormAttr["id"]
 put rigFormOpen("auth/editUser/" & tID, tFormAttr) into gData["formOpen"]

 # FIELD SET
 put rigFormFieldset("Edit User") into gData["fsOpen"]
 put rigFormFieldsetClose() into gData["fsClose"]

 # FORM LABELS
 put "formLabel" into tLabelAttr["class"]
 put rigFormLabel("First Name:", "first", tLabelAttr) into gData["firstLabel"]
 put rigFormLabel("Last Name:", "last", tLabelAttr) into gData["lastLabel"]
 put rigFormLabel("Company:", "company", tLabelAttr) into gData["companyLabel"]
 put rigFormLabel("Phone:", "phone", tLabelAttr) into gData["phoneLabel"]
 put rigFormLabel("Password:", "password", tLabelAttr) into gData["passwordLabel"]
 put rigFormLabel("Confirm Password:", "passwordConfirm", tLabelAttr) into gData["passwordConfirmLabel"]

 # SUBMIT
 put "editSubmit" into tSubmitArr["name"]
 put "Save User" into tSubmitArr["value"]
 put "editBtn" into tSubmitArr["id"]
 put rigSubmitButton(tSubmitArr) into gData["editSubmit"]

 # CHECK POST ARRAY DATA
 if $_POST is an array then
  # VALIDATE THE REQUEST
  if tID <> rigVarPOST("hiddenUserID") then
   rigLogMessage "error", "This form post did not pass the security check.", TRUE
  end if

  put rigVarPost("first") into tData["firstName"]
  put rigVarPost("last") into tData["lastName"]
  put rigVarPost("company") into tData["company"]
  put rigVarPost("phone") into tData["phone"]

  # UPDATE PASSWORD IF IT WAS POSTED
  if rigVarPost("password") <> empty then
   rigSetRules "password", "Password", \
"requiredR|minLengthR[" & tMinPasswordLength & "]|maxLengthR[" & tMaxPasswordLength & "]|matchesR[passwordConfirm]|xssClean"
   rigSetRules "passwordConfirm", "Confirm Password", "requiredR"

   put rigVarPost("password") into tData["password"]
  end if

  # FORM VALIDATION
  if rigFormValidRun("auth/editUser") is TRUE then
   get rigAuthUpdate(tUser["id"], tData)

   rigSetSessFlashdata "message", "User saved."
   # REDIRECT TO AUTH PAGE
   rigRedirect "auth/"
  end if

 end if -- if $_POST is an array then
 put rigValidationErrors("<div class=" & quote & "error" & quote & ">", "</div>") into tErrors
 if tErrors <> empty then
  put tErrors into gData["message"]
 else
  put rigSessFlashdata("message") into gData["message"]
  if gData["message"] is FALSE then
   put empty into gData["message"]
  end if
 end if

 # INPUT FIELDS
 put "first" into tInFirstArr["name"]
 # RE-POPULATE THE FIELD
 put rigSetValue("first", tUser["firstName"]) into tInFirstArr["value"]
 put "50" into tInFirstArr["maxlength"]
 put rigFormInput(tInFirstArr) into gData["first"]

 put "last" into tInLastArr["name"]
 # RE-POPULATE THE FIELD
 put rigSetValue("last", tUser["lastName"]) into tInLastArr["value"]
 put "50" into tInLastArr["maxlength"]
 put rigFormInput(tInLastArr) into gData["last"]

 put "company" into tInCompArr["name"]
 # RE-POPULATE THE FIELD
 put rigSetValue("company", tUser["company"]) into tInCompArr["value"]
 put "100" into tInCompArr["maxlength"]
 put rigFormInput(tInCompArr) into gData["company"]

 put "phone" into tInPhoneArr["name"]
 # RE-POPULATE THE FIELD
 put rigSetValue("phone", tUser["phone"]) into tInPhoneArr["value"]
 put "50" into tInPhoneArr["maxlength"]
 put rigFormInput(tInPhoneArr) into gData["phone"]

 put "password" into tInPassArr["name"]
 # RE-POPULATE THE FIELD
 put rigSetValue("password") into tInPassArr["value"]
 put "50" into tInPassArr["maxlength"]
 put rigFormInput(tInPassArr) into gData["password"]

 put "passwordConfirm" into tInPassConfArr["name"]
 # RE-POPULATE THE FIELD
 put rigSetValue("passwordConfirm") into tInPassConfArr["value"]
 put "50" into tInPassConfArr["maxlength"]
 put rigFormInput(tInPassConfArr) into gData["passwordConfirm"]

 put "hiddenUserID" into tInUserIdArr["name"]
 put tID into tInUserIdArr["value"]
 put "hidden" into tInUserIdArr["type"]
 put rigFormInput(tInUserIdArr) into gData["hiddenUserID"]

 # LOAD VIEW
 get rigLoadView("auth/editUserMainView")

end editUser

Top of Page

Now add the last handler which is needed to delete user data.

command deleteUser
 put "Auth Test Delete User" into gData["pageTitle"]

 put rigFetchSegment(3) into tID

 # FORM OPEN
 put "authForm" into tFormAttr["id"]
 put rigFormOpen("auth/deleteUser/" & tID, tFormAttr) into gData["formOpen"]

 # FIELD SET
 put rigFormFieldset("Delete User Form") into gData["fsOpen"]
 put rigFormFieldsetClose() into gData["fsClose"]

 # FORM LABELS
 put "formLabel" into tLabelAttr["class"]
 put rigFormLabel("Yes:", "confirm", tLabelAttr) into gData["confirmRadioYesLabel"]
 put rigFormLabel("No:", "confirm", tLabelAttr) into gData["confirmRadioNoLabel"]

 # SUBMIT
 put "deleteSubmit" into tSubmitArr["name"]
 put "Submit" into tSubmitArr["value"]
 put "submitBtn" into tSubmitArr["id"]
 put rigSubmitButton(tSubmitArr) into gData["deleteSubmit"]

 # FORM VALIDATION
 if rigFormValidRun("auth/deleteUser") is TRUE then
  put FALSE into tDeleted

  # CHECK IF DEACTIVATION WAS CONFIRMED
  if rigVarPOST("confirm") is "yes" then

   # VALIDATE THE REQUEST
   if tID <> rigVarPOST("id") then
    rigLogMessage "error", "This form post did not pass the security check.", TRUE
   end if

   # CHECK THE USER LEVEL
   if (rigAuthLoggedIn() is TRUE) and (rigAuthIsAdmin() is TRUE) then
    put rigAuthDeleteUser(tID) into tDeleted
   end if

  end if

  # GET AUTH MESSAGES AND REDIRECT TO THE AUTH PAGE
  if tDeleted is TRUE then
   put rigAuthMessages() into tMessages
  else
   put rigAuthErrors() into tMessages
  end if

  rigSetSessFlashdata "message", tMessages
  rigRedirect "/auth"

 else
  put rigValidationErrors("<div class=" & quote & "error" & quote & ">", "</div>") into tErrors
  if tErrors <> empty then
   put tErrors into gData["message"]
  else
   put rigSessFlashdata("message") into gData["message"]
   if gData["message"] is FALSE then
    put empty into gData["message"]
   end if
  end if

  # HIDDEN USER ID FIELD
  put rigAuthUser(tID) into tQueryResult

  if (tQueryResult <> FALSE) and (tQueryResult is an array) then
   put rigDbRow() into tUserRow
   put tUserRow["id"] into tUserID
   put tUserRow["username"] into gData["userName"]
  else
   put empty into tUserID
  end if
  put rigFormHidden("id", tUserID) into gData["hiddenUserID"]

  # RADIO BUTTONS
  put rigSetRadio("confirm", "yes") into gData["confirmYes"]
  put rigSetRadio("confirm", "no", TRUE) into gData["confirmNo"]

  # LOAD VIEW
  get rigLoadView("auth/deleteUserMainView")
 end if
end deleteUser

--| END OF auth.lc
--| Location: ./application/controllers/auth.lc
----------------------------------------------------------------------

Top of Page

The Form Validation File

The rules to validate authentication. Create a file called validation.lc. In it, place the code below and save it to your application/config/ folder.

<?lc

if gRigA is not an array then
  put "No direct script access allowed."
  exit to top
end if

local sValidationConf

# AUTHENTICATION VALIDATION
# LOGIN
put "identity" into sValidationConf["auth/login"][1]["field"]
put "Email" into sValidationConf["auth/login"][1]["label"]
put "trim|requiredR|validEmailR|maxLengthR[100]|xssClean" into sValidationConf["auth/login"][1]["rules"]

put "password" into sValidationConf["auth/login"][2]["field"]
put "Password" into sValidationConf["auth/login"][2]["label"]
put "requiredR|alphaDashR|maxLengthR[40]|xssClean" into sValidationConf["auth/login"][2]["rules"]

put "remember[]" into sValidationConf["auth/login"][3]["field"]
put "Remember me" into sValidationConf["auth/login"][3]["label"]
put "numericR" into sValidationConf["auth/login"][3]["rules"]

# CREATE USER
put "first" into sValidationConf["auth/createUser"][1]["field"]
put "First Name" into sValidationConf["auth/createUser"][1]["label"]
put "trim|requiredR|minLengthR[3]|maxLengthR[50]|alphaDashR|xssClean" into sValidationConf["auth/createUser"][1]["rules"]

put "last" into sValidationConf["auth/createUser"][2]["field"]
put "Last Name" into sValidationConf["auth/createUser"][2]["label"]
put "trim|requiredR|minLengthR[3]|maxLengthR[50]|alphaDashR|xssClean" into sValidationConf["auth/createUser"][2]["rules"]

put "company" into sValidationConf["auth/createUser"][3]["field"]
put "Company" into sValidationConf["auth/createUser"][3]["label"]
put "trim|minLengthR[3]|maxLengthR[100]|alphaDashR|xssClean" into sValidationConf["auth/createUser"][3]["rules"]

put "email" into sValidationConf["auth/createUser"][4]["field"]
put "Email" into sValidationConf["auth/createUser"][4]["label"]
put "trim|requiredR|validEmailR|minLengthR[3]|maxLengthR[100]|xssClean" into sValidationConf["auth/createUser"][4]["rules"]

put "phone" into sValidationConf["auth/createUser"][5]["field"]
put "Phone" into sValidationConf["auth/createUser"][5]["label"]
put "trim|alphaDashR|maxLengthR[20]" into sValidationConf["auth/createUser"][5]["rules"]

put "password" into sValidationConf["auth/createUser"][6]["field"]
put "Password" into sValidationConf["auth/createUser"][6]["label"]
put "requiredR|minLengthR[8]|maxLengthR[40]|matchesR[passwordConfirm]|xssClean" into sValidationConf["auth/createUser"][6]["rules"]

put "passwordConfirm" into sValidationConf["auth/createUser"][7]["field"]
put "Confirm Password" into sValidationConf["auth/createUser"][7]["label"]
put "requiredR" into sValidationConf["auth/createUser"][7]["rules"]

# DEACTIVATE USER
put "confirm" into sValidationConf["auth/deactivate"][1]["field"]
put "Confirmation" into sValidationConf["auth/deactivate"][1]["label"]
put "requiredR|alphaR" into sValidationConf["auth/deactivate"][1]["rules"]

put "id" into sValidationConf["auth/deactivate"][2]["field"]
put "User ID" into sValidationConf["auth/deactivate"][2]["label"]
put "requiredR|numericR" into sValidationConf["auth/deactivate"][2]["rules"]

# FORGOT PASSWORD
put "email" into sValidationConf["auth/forgotPassword"][1]["field"]
put "Email" into sValidationConf["auth/forgotPassword"][1]["label"]
put "trim|requiredR|validEmailR|minLengthR[3]|maxLengthR[100]|xssClean" into sValidationConf["auth/forgotPassword"][1]["rules"]

# RESET PASSWORD
put "newPassword" into sValidationConf["auth/resetPassword"][1]["field"]
put "New Password" into sValidationConf["auth/resetPassword"][1]["label"]
put "requiredR|minLengthR[8]|maxLengthR[20]|matchesR[newPasswordConfirm]|xssClean" into sValidationConf["auth/resetPassword"][1]["rules"]

put "newPasswordConfirm" into sValidationConf["auth/resetPassword"][2]["field"]
put "Confirm New Password" into sValidationConf["auth/resetPassword"][2]["label"]
put "requiredR" into sValidationConf["auth/resetPassword"][2]["rules"]

# CHANGE PASSWORD
put "oldPassword" into sValidationConf["auth/changePassword"][1]["field"]
put "Old Password" into sValidationConf["auth/changePassword"][1]["label"]
put "requiredR" into sValidationConf["auth/changePassword"][1]["rules"]

put "newPassword" into sValidationConf["auth/changePassword"][2]["field"]
put "New Password" into sValidationConf["auth/changePassword"][2]["label"]
put "requiredR|minLengthR[8]|maxLengthR[20]|matchesR[newPasswordConfirm]|xssClean" into sValidationConf["auth/changePassword"][2]["rules"]

put "newPasswordConfirm" into sValidationConf["auth/changePassword"][3]["field"]
put "Confirm New Password" into sValidationConf["auth/changePassword"][3]["label"]
put "requiredR" into sValidationConf["auth/changePassword"][3]["rules"]

# EDIT USER
put "first" into sValidationConf["auth/editUser"][1]["field"]
put "First Name" into sValidationConf["auth/editUser"][1]["label"]
put "trim|requiredR|minLengthR[3]|maxLengthR[50]|alphaDashR|xssClean" into sValidationConf["auth/editUser"][1]["rules"]

put "last" into sValidationConf["auth/editUser"][2]["field"]
put "Last Name" into sValidationConf["auth/editUser"][2]["label"]
put "trim|requiredR|minLengthR[3]|maxLengthR[50]|alphaDashR|xssClean" into sValidationConf["auth/editUser"][2]["rules"]

put "company" into sValidationConf["auth/editUser"][3]["field"]
put "Company" into sValidationConf["auth/editUser"][3]["label"]
put "trim|minLengthR[3]|maxLengthR[100]|alphaDashR|xssClean" into sValidationConf["auth/editUser"][3]["rules"]

put "phone" into sValidationConf["auth/editUser"][4]["field"]
put "Phone" into sValidationConf["auth/editUser"][4]["label"]
put "trim|alphaDashR|maxLengthR[20]" into sValidationConf["auth/editUser"][4]["rules"]

put "password" into sValidationConf["auth/editUser"][5]["field"]
put "Password" into sValidationConf["auth/editUser"][5]["label"]
put "minLengthR[8]|maxLengthR[40]|matchesR[passwordConfirm]|xssClean" into sValidationConf["auth/editUser"][5]["rules"]

put "passwordConfirm" into sValidationConf["auth/editUser"][6]["field"]
put "Confirm Password" into sValidationConf["auth/editUser"][6]["label"]
put "minLengthR[8]" into sValidationConf["auth/editUser"][6]["rules"]

# DELETE USER
put "confirm" into sValidationConf["auth/deleteUser"][1]["field"]
put "Confirmation" into sValidationConf["auth/deleteUser"][1]["label"]
put "requiredR|alphaR" into sValidationConf["auth/deleteUser"][1]["rules"]

put "id" into sValidationConf["auth/deleteUser"][2]["field"]
put "User ID" into sValidationConf["auth/deleteUser"][2]["label"]
put "requiredR|numericR" into sValidationConf["auth/deleteUser"][2]["rules"]

function rigFetchValidationConf
 return sValidationConf
end rigFetchValidationConf

--| END OF validation.lc
--| Location: ./application/config/validation.lc
----------------------------------------------------------------------

Top of Page

The View Files

Create the following view files and save them to a folder called "auth" in your application/views/ folder.

We use multiple views nested in a parent view file. The header view, name it "headerView.lc", is included in all parent views (one fits all):

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">

  <title>[[gData["pageTitle"]]]</title>
  <? return rigCssAsset("authentication.css") ?>

</head>

The view which represents the admin page called "authView.lc":

<body>

  <div id="container" class="adminPage">
    <header>
      <h1>Users</h1>
    </header>

    <div id="main" role="main">

    <div id="infoMessage">[[gData["message"]]]</div>

      [[gData["usersTable"]]]

      <p>[[gData["newUserLink"]]]</p>

      <p>[[gData["logoutLink"]]]</p>

    </div>
  </div> <!--! end of #container -->

</body>
</html>

The parent view of the admin page called "authMainView.lc":

<?
put rigLoadView("auth/headerView", TRUE) into tHeader
put rigLoadView("auth/authView", TRUE) into tContent
return tHeader && tContent
?>

The view used to change a password. It is called "changePasswordView.lc":

<body>

  <div id="container" class="changePassword">
    <header>
    <h1>Change Password</h1>
    </header>

    <div id="main" role="main">

    <div id="infoMessage">[[gData["message"]]]</div>

    [[gData["formOpen"]]]
    [[gData["fsOpen"]]]

    <div>[[gData["oldPasswordLabel"]]] [[gData["oldPassword"]]]</div>

    <div>[[gData["newPasswordLabel"]]] [[gData["newPassword"]]]</div>

    <div>[[gData["newPasswordConfirmLabel"]]] [[gData["newPasswordConfirm"]]]</div>

    [[gData["hiddenUserID"]]]

    <div>[[gData["changeSubmit"]]]</div>

    [[gData["fsClose"]]]
    </form>

    </div>
  </div> <!--! end of #container -->

</body>
</html>

"changePasswordMainView.lc", the parent view of the view above:

<?
put rigLoadView("auth/headerView", TRUE) into tHeader
put rigLoadView("auth/changePasswordView", TRUE) into tContent
return tHeader && tContent
?>

The "createUserView.lc" view:

<body>

  <div id="container" class="createUser">
    <header>
    <h1>Create User</h1>
    <p>Please enter the users information below.</p>
    </header>

    <div id="main" role="main">

      <div id="infoMessage">[[gData["message"]]]</div>

      [[gData["formOpen"]]]
      [[gData["fsOpen"]]]

      <div>[[gData["firstLabel"]]] [[gData["first"]]]</div>

      <div>[[gData["lastLabel"]]] [[gData["last"]]]</div>

      <div>[[gData["companyLabel"]]] [[gData["company"]]]</div>

      <div>[[gData["emailLabel"]]] [[gData["email"]]]</div>

      <div>[[gData["phoneLabel"]]] [[gData["phone"]]]</div>

      <div>[[gData["passwordLabel"]]] [[gData["password"]]]</div>

      <div>[[gData["passwordConfirmLabel"]]] [[gData["passwordConfirm"]]]</div>

      <div>[[gData["createSubmit"]]]</div>

    [[gData["fsClose"]]]
      </form>

      </div>
  </div> <!--! end of #container -->

</body>
</html>

The parent view "createUserMainView.lc":

<?
put rigLoadView("auth/headerView", TRUE) into tHeader
put rigLoadView("auth/createUserView", TRUE) into tContent
return tHeader && tContent
?>

The "deactivateUserView.lc" view:

<body>

  <div id="container" class="deactivate">
    <header>
      <h1>Deactivate User</h1>
      <p>Are you sure you want to deactivate the user '[[gData["userName"]]]'</p>
    </header>

    <div id="main" role="main">

    [[gData["formOpen"]]]
    [[gData["fsOpen"]]]

      [[gData["hiddenUserID"]]]
    <div>[[gData["confirmRadioYesLabel"]]] <input type="radio" name="confirm" value="yes" [[gData["confirmYes"]]] /></div>
    <div>[[gData["confirmRadioNoLabel"]]] <input type="radio" name="confirm" value="no" [[gData["confirmNo"]]] /></div>

     <div>[[gData["deactivateSubmit"]]]</div>

    [[gData["fsClose"]]]
    </form>
    </div>
  </div> <!--! end of #container -->

</body>
</html>

The parent view "deactivateUserMainView.lc":

<?
put rigLoadView("auth/headerView", TRUE) into tHeader
put rigLoadView("auth/deactivateUserView", TRUE) into tContent
return tHeader && tContent
?>

The "deleteUserView.lc" view:

<body>

  <div id="container" class="delete">
    <header>
      <h1>Delete User</h1>
      <p>Are you sure you want to delete the user '[[gData["userName"]]]'</p>
    </header>

  <div id="main" role="main">

  [[gData["formOpen"]]]
  [[gData["fsOpen"]]]

  [[gData["hiddenUserID"]]]
  <div>[[gData["confirmRadioYesLabel"]]] <input type="radio" name="confirm" value="yes" [[gData["confirmYes"]]] /></div>
  <div>[[gData["confirmRadioNoLabel"]]] <input type="radio" name="confirm" value="no" [[gData["confirmNo"]]] /></div>

  <div>[[gData["deleteSubmit"]]]</div>

  [[gData["fsClose"]]]
  </form>
  </div>
  </div> <!--! end of #container -->

</body>
</html>

The parent view "deleteUserMainView.lc":

<?
put rigLoadView("auth/headerView", TRUE) into tHeader
put rigLoadView("auth/deleteUserView", TRUE) into tContent
return tHeader && tContent
?>

The "editUserView.lc" view:

<body>

<div id="container" class="editUser">
   <header>
    <h1>Edit User</h1>
    <p>Please enter the users information below.</p>
   </header>

   <div id="main" role="main">

    <div id="infoMessage">[[gData["message"]]]</div>

    [[gData["formOpen"]]]
    [[gData["fsOpen"]]]

    <div>[[gData["firstLabel"]]] [[gData["first"]]]</div>

    <div>[[gData["lastLabel"]]] [[gData["last"]]]</div>

    <div>[[gData["companyLabel"]]] [[gData["company"]]]</div>

    <div>[[gData["phoneLabel"]]] [[gData["phone"]]]</div>

    <div>[[gData["passwordLabel"]]] [[gData["password"]]]</div>

    <div>[[gData["passwordConfirmLabel"]]] [[gData["passwordConfirm"]]]</div>

    [[gData["hiddenUserID"]]]

    <div>[[gData["editSubmit"]]]</div>

    [[gData["fsClose"]]]
    </form>

    </div>
  </div> <!--! end of #container -->

</body>
</html>

The parent view "editUserMainView.lc":

<?
put rigLoadView("auth/headerView", TRUE) into tHeader
put rigLoadView("auth/editUserView", TRUE) into tContent
return tHeader && tContent
?>

The "forgotPasswordView.lc" view:

<body>

  <div id="container" class="forgotPassword">
    <header>
    <h1>Forgot Password</h1>
    <p>Please enter your email address so we can send you an email to reset your password.</p>
    </header>

    <div id="main" role="main">

    <div id="infoMessage">[[gData["message"]]]</div>

    [[gData["formOpen"]]]
    [[gData["fsOpen"]]]

    <div>[[gData["emailLabel"]]] [[gData["email"]]]</div>

    <div>[[gData["forgotSubmit"]]]</div>

    [[gData["fsClose"]]]
    </form>

  </div>
  </div> <!--! end of #container -->

</body>
</html>

The parent view "forgotPasswordMainView.lc":

<?
put rigLoadView("auth/headerView", TRUE) into tHeader
put rigLoadView("auth/forgotPasswordView", TRUE) into tContent
return tHeader && tContent
?>

The "loginView.lc" view:

<body>

  <div id="container" class="login">
    <header>
      <h1>Login</h1>
      <p>Please login with your email/username and password below.</p>
    </header>

    <div id="main" role="main">
      <div id="infoMessage">[[gData["message"]]]</div>

    [[gData["formOpen"]]]
    [[gData["fsOpen"]]]

    <div>[[gData["identityLabel"]]] [[gData["identity"]]]</div>

    <div>[[gData["passwordLabel"]]] [[gData["loginPassword"]]]</div>

    <div>[[gData["rememberLabel"]]] <input type="checkbox" name="remember[]" value="1" [[gData["chbRemember"]]] /></div>

    <div>[[gData["loginSubmit"]]]</div>

    [[gData["fsClose"]]]
    </form>
  </div>
  </div> <!--! end of #container -->

</body>
</html>

The parent view "loginMainView.lc":

<?
put rigLoadView("auth/headerView", TRUE) into tHeader
put rigLoadView("auth/loginView", TRUE) into tContent
return tHeader && tContent
?>

The "resetPasswordView.lc" view:

<body>

  <div id="container" class="resetPassword">
      <header>
      <h1>Change Password</h1>
      </header>

    <div id="main" role="main">

  <div id="infoMessage">[[gData["message"]]]</div>

  [[gData["formOpen"]]]
  [[gData["fsOpen"]]]

  <div>[[gData["newPasswordLabel"]]] [[gData["newPassword"]]]</div>

  <div>[[gData["newPasswordConfirmLabel"]]] [[gData["newPasswordConfirm"]]]</div>

  [[gData["hiddenUserID"]]]

  <div>[[gData["resetSubmit"]]]</div>

  [[gData["fsClose"]]]
  </form>

  </div>
  </div> <!--! end of #container -->

</body>
</html>

The parent view "resetPasswordMainView.lc":

<?
put rigLoadView("auth/headerView", TRUE) into tHeader
put rigLoadView("auth/resetPasswordView", TRUE) into tContent
return tHeader && tContent
?>

Top of Page

The CSS File

Create a CSS file called authentication.css, in it place the following code and save it to your assets/css/ folder:

body {
  margin: 40px;
  padding: 0;
  font-family: "Lucida Grande", Lucida, Verdana, Geneva, Sans-serif;
  font-size: 12px;
  color: #888;
  background-color: #fff;
}
#container {
  margin-left: auto;
  margin-right: auto;
}
#container.login,
#container.editUser,
#container.createUser,
#container.changePassword,
#container.forgotPassword,
#container.resetPassword {
  width: 400px;
}
#container.adminPage {
  width: 610px;
}
#container.deactivate, #container.delete {
  width: 350px;
}
.formLabel {
  display: inline-block;
  width:  160px;
  margin-bottom: 10px;
}
table {
  width: 600px;
}
th {
  text-align: left;
}
button a {
  text-decoration: none;
}

Try it!

After having installed all those sample files

go to your authentication page (yourDomain.com/auth/) and login as admin using "admin@admin.com" as user id and "revigniter" as password.

Create a new user by clicking on "Create New User". Use your own email address so that you can verify that all works as expected.

Log out.

Check your email account and activate your test registration.

Go to yourDomain.com/auth/logout/ to log out.

Go to yourDomain.com/auth/forgotPassword, enter your email address and check your email account again to reset your password.

Activate / deactivate users using the admin account.

In short: Have fun.

Previous Topic:   Authentication Email Templates
 ::
Top of Page ::
User Guide Home ::
Next Topic:  OTP Authentication

revIgniter :: Copyright © 2009 - 2021 :: Ralf Bitter

redpajama_set_name: RedPajamaGithub


Welcome to this beautiful and inviting home, overlooking the Deer Grove forest preserve. Rarely offered, and highly desirable, this open floor plan features an upgraded kitchen with stainless appliances, custom cabinetry and gorgeous granite counters, open to the shared living and dining rooms. Sliders provide a window to nature and lead to the deck, backing to the lush, wooded landscape. Three bedrooms are located upstairs, including the spacious master suite, dual walk-in closets, and a luxurious bath with separate vanities, as well as two additional bedrooms. The laundry room is conveniently located on the second floor as well. Relax and enjoy a spa-like experience in the English basement steam shower and sauna. Additionally, a large recreation room provides space for play, and is partially being used as an office. High-end finishes, fabulous location, and immaculate presentation define the essence of this lovely home.


text:
Art Impact Awards Assembly and Reception
//PICTURED ABOVE: Sari Wyssbrod is rewarded for her short film, "Bangover." The film will remain in Hockaday's permanent collection. The Annual Art Impact Awards Assembly on April 29 honored Hockaday Visual Arts juniors and...
Endgame: A Marvelous Final Stand
//PICTURED ABOVE: The original six Avengers and Nick Fury team up to save the world and bring back the dusted in their newest movie, Avengers: Endgame. From Black Panther to Infinity War, Marvel movies...
Is Khalid really "Freeing his Spirit?"
Arts + Life, Reviews
Before I begin, I must admit I'm a biased reviewer. I love Khalid. Personally, I love his calming effect and atmosphere in every song. His debut album, "American Teen" won the iHeartRadio Music Award...
ISAS 2019 Recap: Day 2
Arts + Life, News
The second day of ISAS began with beautiful weather. With a full day to come, the campus bustled with even more energetic students moving around to fight the crowds. Unlike the first day, there...
Bold and Bolder: A Review of Billie Eilish's New Album
It wasn't a long time ago that suddenly everyone around me knew the name of Billie Eilish, the 17-year-old younger-than-me pop star whose songs took over all of my friends' Spotify playlists. Even my...
Stealing the Stage at Kidchella
//PICTURED ABOVE: Hockaday Show Choir warms up in preparation for their performance of "Wings" and "Brave" for the guests at KidChella. Junior Chloe Johnson centers the stage, helping to lead their dance. The event...
Hats Off to The Class of 2019
It's 90 Degrees Somewhere
From the ashes of one of Dallas' most iconic and mourned burger joints, rises another, like a blazing, swanky, succulent-filled phoenix. Although hot dogs, patties and Wiener Schnitzels aren't on the menu this time,...
Since Hockaday's roots in 1913, the school has housed priceless art pieces. Ela Hockaday herself was an art collector and befriended famous artists such as Gertrude Stein. Even after the move to the current...
City Slicker: "Art Month" in Dallas
Arts + Life, Photo Essay

redpajama_set_name: RedPajamaCommonCrawl


Healthcare Grade, Assists Care Givers When Transferring Patients, Will Accommodate 9" Tub Wall (Custom Width Available), Deluxe Elongated Open Front Soft Seat, Dual Drop Arm (Secured With Safety Straps), One Step Locking System Easliy Opreates With Single Pull Knob And There Is No Risk Of The Chair Frame Coming Off The Track At Any Time, The Dual Aluminum Rails System Keeps The Chair Rolling Very Secure And Efficient, Safety Belt Increases Safety For Your Resident, Anti-Slip Handgrips, Push/Pull Handle And Fast Drying Removable Mesh Back/Sling, Reinforced At All Stress Related Areas, Personal Pocket Pouch.
MJM Deluxe Enlongated Soft Seat Option Adds Absolute Comfort To Any Of Our Shower Chairs. MJM Soft Seat Is Designed With A Combination Durable Marine And Health Care Grade Material Cover And Resilient Foam And 3/4" Treated Plywood For the Ultimate Durability And Paitent Comfort.


text:
Wiwi Jury
Moldova: Wiwi Jury reviews Diana Brescan with "Breath"
byBogdan Honciuc
The Wiwi Jury, our in-house panel of music unprofessionals, is still in Chisinau, eager to listen to and judge the songs from Moldova's national selection O melodie pentru Europa. We continue with Diana Brescan, who returns to the contest with "Breath". Will it take our breath away or will it be a sigh of relief when it ends? Let's find out!
Diana Brescan – "Breath"
https://www.youtube.com/watch?v=V4rC_HHXwJk
"Breath" reviews
Bogdan: One of my favourite songs in Moldova's selection this year, "Breath" (shouldn't it be "Breathe" though?) is very demanding vocally. Nevertheless, Diana Brescan delivers it almost flawlessly, despite the less than perfect sound system in the TRM studio. As a side note, I laughed when she brought out the unnecessary chair. Watch out for Diana to challenge Sunstroke Project for the ticket to Kyiv!
Robyn: This is easily one of the best entries in the national selection this year. Even with the questionable technical set up of the live audition, the potential of the song and the quality of Diana's voice is apparent. My only reservation is that the verses sometimes feel a little plodding. It will be interesting to see how this comes across at the semi-final.
Deban: For a song titled "Breath", this is too wordy. The lyrical overload highlights several enunciation issues. Furthermore, Diana Brescan's delivery lacks seduction or spark, making this a karaoke effort at best.
William: The beginning is atmospheric and brooding, but Diana seems poised to pass out. Then from 1:10 she gets angsty and angry, as if her psychiatrist has prescribed the wrong dosage of Cymbalta. In both sections the pronunciation is questionable and I had to pause to figure out if this was in English. (Apparently it is). It's a no from me.
Chris: There's the makings of a good song here, perhaps limited by the production and staging Diana had on offer. The chorus feels like it's trying to be bigger than it is though. The slight tempo change from the verses doesn't quite mesh. It either makes the chorus feel out of place, or the verses become boring. I can't tell which right now.
In our Moldova Wiwi Jury, we have 17 jurors but only room for 5 reviews. The rest of our scores can be found below:
Bernardo: 5/10
Antranig: 4/10
Anthony: 8/10
Cinan: 6/10
Dayana: 5.5/10
Patrick: 3/10
Josh: 6/10
Kristin: 6/10
Luis: 5/10
Sami: 5/10
Jason: 5/10
Zakaria: 5/10
Before calculating the average score, the highest and lowest scores are dropped. This is to remove outliers and reduce potential bias. We have removed a low of 3 and a high of 8.
Wiwi Jury Verdict: 5.47/10
SEE OUR LIST OF O MELODIE PENTRU EUROPA RANKINGS
Vote for your favourites in our Moldova poll
READ MORE MOLDOVA EUROVISION NEWS
Diana Brescan
O melodie pentru Europa
O melodie pentru Europa 2017
Bogdan Honciuc
What is your favourite Charlotte Perrelli Melodifestivalen song?
Greece: Eurovision 2011 singer Loucas Yiorkas goes ethnic with "Den Pao Sti Douleia"
byKristin Kristjans
Israel: Online voting opens in HaShir Shelanu L'Eurovizion 2021, as Eden Alene's three music videos are released
Norway: HoD Stig Karlsen says KEiiNO face tough competition in "most important MGP ever"
Melodifestivalen 2021: Christer Björkman reported to host, Måns Zelmerlöw and Lena Philipsson among special weekly co-hosts
byPablo Nava
The Wiwi Jury reveals their favourites in Albania's Festivali i Këngës 59
UMK 2021: Finland will reveal the 7 finalists on January 13
Deck the halls: 16 new festive songs from The Mamas, Anna Bergendahl, Secret Garden and more
Festival da Canção 2021: 10 artists we would like to see in Portugal's selection
New music this week: 25 songs from Eleni Foureira, Poli Genova, Aksel Kankaanranta and more
Posted on November 29, 2020 December 1, 2020
No! I don't like that!
Come on Moldova! In this semi, you will most likely not survive!
Antranig Shokayan
I'm disappointed with this song because she was my favourite last year. This isn't anywhere near as good.
an esc fan
Moldova you are in the first semifinal, the "bloodbath", your only friends Ukraine and Romania are in semifinal 2, don't experiment, don't risk, just thank your luck that SunStroke Project wants to paticipate.
Come on, don't laugh about their studio, this is not meant for the public to see, and they show it anyway. They could just tell us about the last 6, or just the chosen one, without any explanation. How many other countries are so transparent ?
Don't bother watching the video linked here – audio quality is completely lackluster. There's another on youtube where you can hear the studio version. It sounds pretty nice.
Congrats to Moldova !!!!!!!!!!!
They invented the travel machine and we are finally back in the 90's…… TVM studio …. SLAAAY.
Jamaraqueer
The TVM studio looks so bad! I feel bad for all of the acts!


Jennifer Lea Reynolds is a writer whose articles have been published on The Huffington Post, Lipstick & Politics, BlogHer, The Budget Fashionista and Natural News. She's also a columnist for Model Aviation magazine, where she writes about life observations pertaining to the hobby. A weight loss success story, Reynolds maintains her own site, FlabbyRoad.com, which educates and inspires others about nutrition, fitness, and body image. She's held advertising copywriter and public relations careers throughout her life. After living in New Jersey for more than 20 years, she now calls the Lakes Region of New Hampshire home where she lives with her husband and two cats. She enjoys photography and kayaking and admits to still having a thing for 80s music.


text:
Raabta Official Trailer Starring Sushant And Kriti Raises The Expectations
The much-awaited trailer of Sushant Singh Rajput and Kriti Sanon starrer 'Raabta' is finally out now and it raises the expectations of the film. Watch the Raabta Official Trailer.
Raabta appears to be an intense story connecting two different eras. Which also strongly resemble director SS Rajamouli's film Magadheera, starring Ram Charan Teja.
The trailer also includes a recreation of the hit melody 'Raabta' from Saif Ali Khan-starrer 'Agent Vinod', which is the most most soothing element plays in the background during the trailer.
At the film's trailer launch, Kriti said, "I really feel that I was meant to be a part of the film. I had some raabta with Raabta." Her co-star Sushant revealed that he and director Dinesh Vijan had discussed four scripts, and Raabta was not one of them. However, when Dinesh casually mentioned the idea of Raabta, Sushant could not get it out of his head.
Irrfan Khan lending his voice in the film narrating the story of Raja and Rani, defintly Irrfan's voice added more weight to the trailer.
Director Dinesh Vijan said in a statement: "We needed a soothsayers' voice for the trailer. Irrfan's voice is amazing and distinct. We were flying to Georgia when I asked Irrfan if he could do a small voice-over for Raabta. He agreed and then asked me the details.
Directed by Dinesh Vijan, Raabta, is a romantic drama, which was extensively shot in Budapest is set to release on June 9.
'Manikarnika: The Queen Of Jhansi' new song: 'Vijayi Bhava
Amitabh Bachchan Response To Brad Hodge On Behalf Virat Kohli | Only Shahenshah Can Do This
Make This Valentine Special For Your Loved One With the Special Gift – Gossip Glue
Haseena Parker Teaser | Shraddha Kapoor Looks Real Queen Of Mumbai
Justin Bieber Took Country By Storm | Latest Gossip From Bieber Concert


1 What is Gerstmann Syndrome?
Gerstmann Syndrome is a rare neurological degenerative disorder, develops due to lesion obtained due to developmental malfunctioning or brain injury, which affects the dominant parietal lobe present at the angular gyrus.
Both children and adult can affect with this disease, but often it has identified in adults after acquired lesion obtains through brain injury. Even it has been assumed that Gerstmann Syndrome may be characteristic features of Alzheimer disease. The cerebrovascular event also can cause of Gerstmann Syndrome development. Yet now, no identified genetic component is responsible for developing the Gerstmann Syndrome and no history of inherited disorder. The childhood type of Gerstmann Syndrome may arise because of isolation with bright and intellectual mental function or brain injury 1,5.
Main four symptoms are considered as classic features of Gerstmann Syndrome. All four symptoms arise due to a deficit of sensory abilities.
Affected individual unable to express thoughts in writing and clinically the condition is termed as agraphia or dysgraphia. The typical findings of agraphia or dysgraphia are unreadable and untidy writing, the irregular formation of letters, a jumble of capital and short alphabets or print and cursory writing, uneven size and shapes of alphabets and incomplete letters.
Unable to solve easy arithmetical calculations and clinically termed as acalculia.
Loss of Recognition capability of one's own or another's fingers and clinically termed as finger agnosia.
But in very rare cases, all four symptoms appear without learning disability for the same individual. When agraphia, acalculia, agnosia and incapability of side discrimination without mental retardation is typical characteristics and referred to as "pure" Gerstmann syndrome. Usually, all four mentioned clinical characteristics are present with other deficits, But it is also possible that all four symptoms may not present at all together.
In addition, some individuals also have a problem in expressing their feeling tough speech, even they cannot properly understand other's speech (aphasia). They may have difficulty in reading and understanding of spelling.
Children usually have developmental Gerstmann syndrome, which is recognizable after school admission. They may have poor handwriting, difficulty in understanding of simple calculations and spelling, unable to copying or tracing simple words or drawing2,3,4.
Cerebrovascular disease, like stroke or another injury to the brain, in which blood circulation become impaired into the brain is one of the major cause of developing Gerstmann Syndrome in adults. In Gerstmann syndrome, parietal lobes of the brain become affected. Therefore, symptoms are all related to lack of sensory and perception, even understanding of sensory input become impaired, as parietal lobes of the brain are responsible for these types of mechanism.
Traumatic brain injury or a brain tumor in the parietal lobes can also cause similar symptoms associated with Gerstmann syndrome. The cause of developmental Gerstmann syndrome in children is not yet understood properly. It is assumed that brain damage at the particular region of the brain can be a cause of the onset of Gerstmann syndrome1,2.
Both male and female equally have the risk of development of Gerstmann syndrome, though the incidence of this disease is very rare in general population. The disease name is derived from Dr. Josef Gerstmann, a Viennese neurologist, who first described this disorder in 19242.
Differential diagnosis is performed in Gerstmann syndrome after a symptomatic analysis found all four neurological symptoms in adults to exclude the chance of other possible underlying causes.
The primary diagnosis is based on symptomatic analysis and in the case of children it can usually possible at school going age. The symptom analysis is possible by close observation of spelling problems, unsolved simple calculation, poor handwriting, etc. Trouble in left and right side distinction can be measured by asking the affected children to show right-hand index finger and they generally fail to do, even simple drawing they cannot draw 2.
There is no treatment available for curing Gerstmann syndrome. Healthcare providers recommend counseling services, special education and related rehabilitation in case of developmental Gerstmann syndrome.
In the case of adults, neurological conditions need to treat, so that patient management can be possible. Surgical intervention may require in neurological condition to improve the condition.
Exceptional, symptoms of Gerstmann syndrome diminish over a period of time 1, 2,5.
Depending on the underlying cause, many symptoms may diminishing with time in adults. But in children, this outcome does not properly measure, because it has been assumed that most children possibly do not defeat their deficit, but become skilled in adjusting with their difficulties 5.


text:
Georges Charachidzé (Giorgi Sharashidze; ) (February 11, 1930 – February 20, 2010) was a French-Georgian scholar of the Caucasian cultures. His most important works focused on the history of Georgian feudalism, pagan religious beliefs of the Georgians as well as the Caucasian comparative mythology and the North Caucasian languages.

Family
Georges Charachidzé was born into the Georgian émigré community of Paris. His father David Sharashidze (French: Charachidzé; 1886–1935) was a journalist and a member of the Constituent Assembly of Georgia before being forced to leave his homeland following the Soviet takeover of Georgia in 1921. Sentenced to death by the Soviet government, Charachidzé had moved to Paris, where he had married a young French teacher, who gave birth to Georges Charachidzé in 1930.

Career
Georges Charachidzé grew up speaking both Georgian and French. In 1953, he obtained the supervision of Georges Dumézil, a leading French scholar of the Caucasus, for his doctoral thesis, which was published, in 1968, as his first book Le système religieux de la Géorgie païenne ("The religious system of pagan Georgia"). In 1965, he accompanied Dumézil to Turkey for a field-work study of the Caucasian communities, descending from the 19th-century refugees of the Russian conquest wars in the Caucasus. While in Turkey, he assisted Dumézil in the reconstruction of the vanishing Ubykh language and in recording its last living speaker, Tevfik Esenç, who died in 1992.

Charachidzé produced several studies on the pagan religious systems of the Georgians and other Caucasians, the Georgian feudalism, the Avar grammar, Ubykh texts, and the Indo-European–Caucasian interaction. Charachidzé was a regular contributor to the long-running, Paris-based journal for Caucasian studies Bedi Kartlisa, founded and sponsored by the Georgian émigrés Kalistrat Salia and Nino Salia. In 1985, Charachidzé, together with Dumézil, founded the successor journal Revue des Etudes Géorgiennes et Caucasiennes. Charachidzé taught Georgian at the Institut national des langues et civilisations orientales from 1965 to 1998. He served as the president of the Société de Linguistique de Paris in 1984. He was also a member of the Académie des Inscriptions et Belles-Lettres. Georges Charachidzé died in Paris in 2010.

Bibliography
Some of the most important works by Charachidzé are:
Charachidzé, G. 1960. Travail et mort dans la montagne géorgienne. L'Ethnographie 54: 45-62.
Charachidzé, Georges. 1968. Le système religieux de la Géorgie païenne: analyse structurale d'une civilisation. Paris: Maspero.
Charachidzé, Georges. 1971. Introduction à l'étude de la féodalité géorgienne: le Code de Georges le Brillant. Paris: Librairie Droz.
Charachidzé, Georges. 1979. L'aigle en clé d'eau: un exemple d'inversion conservante. La fonction symbolique. Michel Izard & Pierre Smith, eds. Paris: Gallimard, pp 83–104.
Charachidzé, G. 1981. "Géorgie. La religion et les mythes des Géorgiens de la montagne." Dictionnaire des mythologies et des religions des sociétés traditionnelles et du monde antique. (ed. Yves Bonnefoy). Vol 1, pp 451–459. Paris: Flammarion.
Charachidzé, G. 1981. "Arménie. La religion et les mythes." Dictionnaire des mythologies et des religions des sociétés traditionnelles et du monde antique. (ed. Yves Bonnefoy). Vol 1, pp 67–69. Paris: Flammarion.
Charachidzé, G.. 1981. "Caucase du Nord." Dictionnaire des mythologies et des religions des so-ciétés traditionnelles et du monde antique. (ed. Y. Bonnefoy). Vol 1, pp 129–132. Flammarion.
Charachidzé, G. 1981. "Les Ossètes." Dictionnaire des mythologies et des religions des sociétés traditionnelles et du monde antique. (ed. Y. Bonnefoy). Vol 2, pp 215–218. Paris: Flammarion.
Charachidzé, G. 1986. Prométhée ou le Caucase. Paris: Flammarion.
Charachidzé, G. 1987. La mémoire indo-européenne du Caucase. Paris: Hachette.

References

1930 births
2010 deaths
20th-century French historians
Linguists from France
Ubykh language
French people of Georgian descent
Kartvelian studies scholars
French philologists
Indo-Europeanists
Mythographers
Members of the Académie des Inscriptions et Belles-Lettres
Writers from Paris
Comparative mythologists
French male writers

redpajama_set_name: RedPajamaWikipedia


Absolutely amazing!! Silver Label was absolutely amazing to work with and the guests at our wedding continue to rave on about how much they loved the photobooth. The photos are an excellent keepsake of the night and make us laugh every time we look at them! Having a photobooth also helped us make sure we got a picture of each and every guest. We love the photo album they put together for us with notes from the guests in the photos. Also loveee the little video clips are guests were able to make for us to keep forever - too funny! I would recommend them to anyone and will definitely use their service again in the future! Thank you for everything Silver Label!!!
-Nicole M. Thank you guys so much for coming out! We had a photobooth at the Gallery a couple of years ago and I received many comments that yours was much more professional and fun! Everyone seemed pretty impressed with you guys, as they should have been.Eeveryone enjoyed themselves and thank you again for staying that extra little bit of time. We truly appreciated it. We will most definitely keep you in mind for future events. Many Thanks.
Joel and I would just like to thank you for helping us out on our big day. The pPhotobooth was an absolute hit; people are still talking about it and I know some couples want it at their wedding. Your booth had a great set up with all the choices for colours and for props. You were great to work with and I will definitely be recommending your services to others! Thanks again!
I wanted to send a message to THANK you for Saturday. This was the first time that we have ever used anything other than face painting for our community events…and we believe it was hands down a great choice. Lots of traffic….and everyone left with a smile on their face. We had such a great experience with Silver Label and hope to once again use your services.
Fantastic Photo Booth, such a huge hit with our guests who are still talking about it - thanks again We recommended to my niece and she has just booked for her upcoming wedding. Happily recommend to anyone, loads of fun and memories!!
- Gwen C. Thank you so much for an amazing night! You guys were such a hit and made it sooo much fun! Amazing crew and you had some great props! Definitely one of the highlights of the day! Thanks again!
Hey guys, Thanks again, you guys did an amazing job and we will be recommending you to everyone.
Amazing company! We absolutely loved how much fun your photobooth was, not to mention your high degree of professionalism and attention to detail! We are especially thankful to Dan who was always available to us, making all sorts of recommendations and designing a ton of templates for us to choose from! We will definitely be recommending Silver Label Entertainment to all of our friends for any event!! Thank you so much!


Matters relating to Central deputation of IPS officers from the level of DIG to DG.
Preparation of offer list of DIG and above level IPS officers for central Deputation.
Any other items of work specifically entrusted.


Sumi™ inks are available as well to tattoo artists. These inks will have a very smooth grey appearance in the skin and are mixed in similar ways mentioned in the grey wash technique. There are some manufactures that are selling Sumi™ inks for tattoo purposes, but they can also be purchased at art supply in solid bar form. The bars must be ground and mixed with an agent prior to tattooing. Any time there is a material that is not intended for tattooing and the source is not designed for the use in the skin, it is important to autoclave the liquid.


MySafePass allows you to organize and manage passwords for all your various Web accounts. It encrypts and saves your passwords in a file. MySafePass lets you categorize and keep any number of different user names (IDs) and passwords and other related information, using one or more master passwords.


Author(s) Esposito, John L.; Esposito, John L.
This exceptionally successful survey text introduces the teachings and practice of Islam from its earliest origins up to its contemporary practice. John L. Esposito, an internationally renowned expert on Islam, traces the development of Islam and its impact on world history and politics.Lucidly written and expansive in scope, Islam: The Straight Path, Updated Fifth Edition, provides keen insight into one of the world's least understood religions. It is ideally suited for use in courses on Islam, world religions, comparative religions, and Middle East history and culture.A FREE 6-month subscription to Oxford Islamic Studies Online (www.oxfordislamicstudies.com), edited by John L. Esposito, is included with the purchase of every new copy of this text.


text:
import { Router, RouterConfiguration } from 'aurelia-router'
import { RessourceStadium, RessourceCommonAppName, RessourceTeamTableSettingsMenu, RessourceTransferMarketSellingSettingsMenu, RessourceTransferMarketAmateurTableSettingsMenu, RessourceTransferMarketProfessionalsTableSettingsMenu, RessourceTransferMarketOfferTableSettingsMenu, RessourceStrengthAwpLimitsSettingsMenu } from "../Common/Ressource"

export class App {
  router: Router;
  ressourceSettingsPageAddonName: string;
  ressourceStadium: string;
  ressourceTeamTable: string;
  ressourceTmSelling: string;
  ressourceTmAmateurs: string;
  ressourceTmProfessionals: string;
  ressourceTmOffers: string;
  ressourceTmAmateur: string;
  ressourceStrengthAwpLimits: string;

  constructor() {
    this.ressourceSettingsPageAddonName = new RessourceCommonAppName().value().valueOf();
    this.ressourceStadium = new RessourceStadium().value().valueOf();
    this.ressourceTeamTable = new RessourceTeamTableSettingsMenu().value().valueOf();
    this.ressourceTmSelling = new RessourceTransferMarketSellingSettingsMenu().value().valueOf();
    this.ressourceTmAmateurs = new RessourceTransferMarketAmateurTableSettingsMenu().value().valueOf();
    this.ressourceTmProfessionals = new RessourceTransferMarketProfessionalsTableSettingsMenu().value().valueOf();
    this.ressourceTmOffers = new RessourceTransferMarketOfferTableSettingsMenu().value().valueOf();
    this.ressourceStrengthAwpLimits = new RessourceStrengthAwpLimitsSettingsMenu().value().valueOf();
  }

  configureRouter(config: RouterConfiguration, router: Router) {
    config.title = this.ressourceSettingsPageAddonName;
    config.map([
      { route: ['', 'SettingsPage/application/application'], name: 'application', moduleId: 'SettingsPage/application/application', nav: false, title: 'Welcome' },
      { route: 'SettingsPage/stadium/settings-stadium', name: 'settings-stadium', moduleId: 'SettingsPage/stadium/settings-stadium', nav: true, title: this.ressourceStadium },
      { route: 'SettingsPage/logging/settings-logging', name: 'settings-logging', moduleId: 'SettingsPage/logging/settings-logging', nav: false, title: "Logging" },
      { route: 'SettingsPage/team-table/settings-teamtable', name: 'settings-teamtable', moduleId: 'SettingsPage/team-table/settings-teamtable', nav: true, title: this.ressourceTeamTable },
      { route: 'SettingsPage/tm-selling/settings-selling', name: 'settings-tm-selling', moduleId: 'SettingsPage/tm-selling/settings-tm-selling', nav: true, title: this.ressourceTmSelling },
      { route: 'SettingsPage/tm-offer-table/settings-tm-offer-table', name: 'settings-tm-offer-table', moduleId: 'SettingsPage/tm-offer-table/settings-tm-offer-table', nav: true, title: this.ressourceTmOffers },
      { route: 'SettingsPage/tm-amateur-table/settings-tm-amateur-table', name: 'settings-tm-amateur-table', moduleId: 'SettingsPage/tm-amateur-table/settings-tm-amateur-table', nav: true, title: this.ressourceTmAmateurs },
      { route: 'SettingsPage/tm-pro-table/settings-tm-pro-table', name: 'settings-tm-pro-table', moduleId: 'SettingsPage/tm-pro-table/settings-tm-pro-table', nav: true, title: this.ressourceTmProfessionals },
      { route: 'SettingsPage/strength-awp-limits/settings-strength-awp-limits', name: 'settings-strength-awp-limits', moduleId: 'SettingsPage/strength-awp-limits/settings-strength-awp-limits', nav: true, title: this.ressourceStrengthAwpLimits },
    ]);

    this.router = router;
  }
}


text:
Three wounded in YouTube HQ shooting
Published Tue, Apr 3 2018 4:16 PM EDT Updated Tue, Apr 3 2018 11:50 PM EDT
Jillian D'Onfro@jillianiles
At least three people are injured after a shooting at YouTube's headquarters in San Bruno, California, police confirm.
A female suspect is dead from a self-inflicted gunshot wound, NBC News reports.
San Bruno police: Female suspect is deceased
A woman injured three people and died of a self-inflicted gun shot wound at YouTube's headquarters in San Bruno, California on Tuesday, police say.
The female suspect who opened fire and is now dead was likely motivated by a domestic-related dispute, NBC News reports based on conversations with multiple senior law enforcement officials. Police have not released an official comment on the shooter's motives.
San Bruno Police Chief Ed Barberini said in a press conference that three victims were found on the scene with gunshot-related injuries, and one person was deceased with a possibly self-inflicted gunshot wound.
Three victims were taken to San Francisco General Hospital and a hospital administrator said in a press conference that one was in fair condition, one was in serious condition, and one patient was in critical condition.
Female suspect dead at YouTube incident says NBC
Barberini said that at 12:46 PM San Bruno police received numerous phone calls about gunshots at YouTube's offices, which are separate from Google's main campus in Mountain View, and that police were on the scene within two minutes.
Several people identifying themselves as YouTube employees on Twitter posted about their experiences at the office:
Todd Sherman, who lists himself as a product manager at YouTube on his Twitter profile, wrote a series of tweets saying that he heard running while in a meeting and that when he exited the room, he heard that there was an active shooter.
Meanwhile, someone from a nearby office tweeted photos of people evacuating YouTube's building.
Google CEO Sundar Pichai has sent a memo to all employees calling the shooting an "unimaginable tragedy" and calling on employees to come together to support the YouTube team.
Earlier, Google posted on Twitter that the company was coordinating with authorities.
According to YouTube's website, there are over 1,100 YouTubers at the San Bruno YouTube office.
President Trump responded to the incident on Twitter, sending his "thoughts and prayers" to everyone involved.
Alphabet Class A


text:
010PHP
home about us contact Speak at our Meetup
Speak at our Meetup
It all started back in 2013. To be precise we founded this group on Friday the 21st of June in 2013, with our first Meetup on Thursday July 11th of the same year. We started as a small group of a few PHP enthusiasts, going to bars and cafes to talk PHP and the latest innovations.
Whether it was the latest PHP release or tooling such as Vagrant or Phing, we were talking about it. It didn't took much effort to invite other like-minded people to attend our gatherings.
The cornerstones of 010PHP are to provide a easy, accessible and fun way of staying up to date with the PHP environment. During these past years we've managed to create a safe environment where learning and networking are made available to people, developers or not, of all age and location.
Our Meetups are not solely focused on PHP but also contain topics such as DevOps, Agile, Personal Development and other interesting areas.
With now hosting our Meetups on every second Thursday of each month we've managed to grow a community with over 1300 members on Meetup.com, with a monthly average of 45 attendees joining in on our events.
Our community is made possible by the help from its amazing members and companies who support us by sponsoring our events. Without them we wouldn't be the success we are today.
GitHub image/svg+xml
YouTube image/svg+xml
Instagram image/svg+xml
Twitter image/svg+xml
Meetup.com image/svg+xml
© 2013 / 2021 - 010PHP. All Rights Reserved. No developers were harmed in the development of this website.
Icons made by Tomas Knop, Freepik, Flat Icons and Pixel perfect from www.flaticon.com


Add the images of the monuments and countries from the zip file given, to the slide. Check the picture below.
In the first step of the wizard, set the monuments as the drag sources. To select the monuments simultaneously, press CTRL and click them. Click Next.
During the last step of the wizard, two text captions appear on the stage-Type success text here, and Type failure text here. Now, click into these captions to edit the feedback messages which the user gets on either passing or failing the assessment. You can also customize the properties of the text, such as color, size, alignment, and font style.
A Submit button also appears on the slide in the last step of the wizard. So, the user has to click Submit to complete the task given to them.
Similarly you can check the On Reject option, or Hint option and set the appropriate message.
You can choose to send the drag source to its original position if the user accidentally moves it. You can also let the user redrag it if they don't drop it at the correct point. Use the Interactions Properties in the Options panel under the Drag and Drop tab to achieve these actions.
As in the previous section, add the images of monuments and countries from the zip file given, to the slide.
You can also use drag-and-drop interactions to let the users group similar items from a collection of items. This task is achieved by using the option Types. As an example, let's create a project to separate fruits and vegetables from their mix.
Add the images of fruits and vegetables from the zip file given, to the slide.
Select all the fruit items simultaneously. To name this group as Fruits, click the + symbol against the Add To Type option on the wizard toolbar.
Let's add the drag-and-drop interaction given in the first section of this article to a quiz.


text:
from flask import Flask, jsonify, abort, request
import validictory

app = Flask(__name__)

users = []
groups = []

def find_user(userid):
    user = next((u for u in users if u['userid'] == userid), None)
    return user

def find_group_users(group):
    userlist = [u['userid'] for u in users if group in u['groups']]
    return userlist

def check_json_user_req(req, userid):
    data = req.json
    schema = {"type": "object",
              "properties": {"first_name": {"type": "string"},
                             "last_name": {"type": "string"},
                             "userid": {"type": "string"},
                             "groups": {"type": "array"}}
              }
    try:
        validictory.validate(data, schema)
    except:
        abort(400)
    if userid != request.json['userid']:
        abort(400)

@app.route('/users/<userid>', methods=['GET'])
def get_user(userid):
    """
        GET /users/<userid>
        Returns the matching user record or 404 if none exist.
    """
    user = find_user(userid)
    if user:
        return jsonify(user)
    else:
        abort(404)

@app.route('/users/<userid>', methods=['POST'])
def add_user(userid):
    check_json_user_req(request, userid)
    user = find_user(userid)
    if user:
        abort(409)
    for g in request.json['groups']:
        if g not in groups:
            abort(422)
    newuser = {
        'userid': request.json['userid'],
        'first_name': request.json['first_name'],
        'last_name': request.json['last_name'],
        'groups': request.json['groups']
    }
    users.append(newuser)
    return jsonify(newuser), 201

@app.route('/users/<userid>', methods=['PUT'])
def mod_user(userid):
    check_json_user_req(request, userid)
    for u in users:
        if u['userid'] == request.json['userid']:
            u['first_name'] = request.json['first_name']
            u['last_name'] = request.json['last_name']
            u['groups'] = request.json['groups']
            return jsonify(u), 200
    abort(404)

@app.route('/users/<userid>', methods=['DELETE'])
def delete_user(userid):
    user = find_user(userid)
    if user:
        users.remove(user)
        return jsonify({'result': True}), 204
    else:
        abort(404)

@app.route('/groups/<group>', methods=['GET'])
def get_group(group):
    if group in groups:
        result = find_group_users(group)
        if result == []:
            abort(404)
        return jsonify({'users': result}), 200
    else:
        abort(404)

@app.route('/groups/<group>', methods=['POST'])
def add_group(group):
    if group in groups:
        abort(409)
    else:
        groups.append(group)
        return jsonify({'result': True}), 201

@app.route('/groups/<group>', methods=['PUT'])
def mod_group(group):
    if not request.json:
        abort(400)
    userlist = []
    if group in groups:
        for u in users:
            if group in u['groups']:
                u['groups'].remove(group)
            if u['userid'] in request.json['users']:
                userlist.append(u['userid'])
                u['groups'].append(u['userid'])
        return jsonify({'users': userlist}), 200
    else:
        abort(404)

@app.route('/groups/<group>', methods=['DELETE'])
def delete_group(group):
    if group in groups:
        for u in users:
            if group in u['groups']:
                u['groups'].remove(group)
        return jsonify({'result': True}), 204
    else:
        abort(404)

if __name__ == '__main__':
    app.run(debug=True)


This Fall wreath inspired by Anthropologie's Terrain will make a gorgeous statement on your front door for Thanksgiving. Learn basic principles of wreath-making and how to use a wire wreath form. This is a dried wreath, so with proper care, it will last from year to year! Finished wreath is approximately 18-24 inches round.
Cost: $55 per person. Includes expert instruction, all project materials, coffee bar and snacks, and girl time. All workshops are BYOB!


text:
Curbed Miami homepage Miami
Curbed Miami main menu
For Sale
in Miami
For Rent
in Miami
Sold Homes in Miami
Miami Beach penthouse at Three Hundred Collins sells for $5.1M
A record for a non-waterfront condo residence in South Beach
By Josh Baumgard May 10, 2017, 3:36pm EDT
A rendering of Three Hundred Collins in South Beach
Courtesy of Three Hundred Collins
Penthouse 2 at Three Hundred Collins in Miami Beach just sold for $5.1 million.
The 2,699-square-foot residence has three bedrooms, three and a half bathrooms, and nearly 900 square feet of outdoor space. All residences include white oak flooring, stone finishes, custom Thomas Juul-Hansen kitchens, and wrap-around terraces.
It's the biggest sale on a per-square-foot basis ($1,890) for a dry condominium in South Beach, according to Darryl Fox and Joseph Schafer of One Sotheby's International Realty, who both brokered the deal.
The JMH development is comprised of 19 units and is expected to be completed this summer. Among the remaining three residences is Penthouse 1, which is offered at $6.45 million by Dina Goldentayer and Sladja Stantic. Amenities include a rooftop pool and beach service.
The property broke ground in February 2016.
Next Up In Sold Homes in Miami
Three-story Brickell Flatiron penthouse fetches $13.2M [Updated]
Zaha Hadid's Miami Beach condo fetches $5.75M
Musician Nicky Jam drops $3.4M on contemporary Miami Beach home
Sharp contemporary Miami Beach estate fetches $19.25M
Marc Anthony identified as buyer of $19M Bacardi estate in Coral Gables
Thomas Kramer's former Star Island estate sells for $33M
Celine Dion's Florida home actually sold for $28M Celine Dion has finally found a buyer for her oceanfront Florida mansion equipped with a water park in the backyard.After initially hitting the market for a whopping $72 million in August 2013, the 20,000-square-foot estate in Jupiter Island has sold for $38.5 million.
Miami's 20 best secret gardens, parks, and green spaces, mapped Lesser-known spaces across the Magic City
Star Island is a Tiny Neighborhood of Massive Houses & Drama