Skip to main content
Inspiring
April 21, 2006
Question

UDF ?? Or some other way ??

  • April 21, 2006
  • 3 replies
  • 547 views
I'm trying to get ideas here.

I have a page that allows users to edit some subscription information. I
have it set so if they change their email address, from what was originally
in the DB, the system sets them to a 'renewed' status in the db.

Now, what I'd like to have happen is to send them a email that they would
need to 'reconfirm' in order for them to start receiving emails at this new
address. Right now I have it set so that when users register, they get a
email (handled by the cfm page that proccesses their subscription
information the 1st time).

I also have a cfm page that runs as a automated process once a week to send
emails to ALL users who are unverified or reverified.

Is there a way to combine some of these features?

Can I set the page that runs as a automated process as a UDF? In some
instances I would need to pass specific user data to it, when it runs as a
automated process I would need it to pull all the info from the db like its
doing now.....

So.....I guess I'm looking for a little help on the best way to set this
up.......

Suggestions would be greatly appreciated!
Thanks,
Steve


    This topic has been closed for replies.

    3 replies

    Known Participant
    April 23, 2006
    PaulH *ACE* wrote:
    >actually it's now "good" practice to use structKeyExists() for structures.

    Right, except that we're checking for the existance of the structure itself, not the existance of a key in the structure.

    The cf docs tell us that function will return "True, if key is in structure; if structure does not exist, ColdFusion throws an exception." I don't want an exception, I want a valid boolean result. I should also mention here, that I'm not big on using cftry/cfcatch to overcome stuff like this, especially when IsDefined or ParameterExists will return a proper boolean value if the structure exists.

    Now, once I know the structure exists, I'd certainly use structKeyExists() to determine if certain keys existed. In the case of a function or custom tag, I'd use structKeyExists() to find out if any optional arguments were passed and behave accordingly.


    I've heard that argument for why not to use ParameterExists, but it still works in my installation of ColdFusion, so I'd rather not have to go change possibly hundreds of lines of code and then have to test my entire system with the changes, when I've got new code that I'm developing every day. That said, if I ever have a client who upgrades to CFMX7 (or whatever the latest version is at the time), then I'm sure I'll see during the development process if that function throws an exception.

    Actually, that may come sooner than I expect since my current client wants more and more reporting done, and my recommendation has been to move to CF7. I suppose it's a good enough reason to write all brand new code using the newest functions. I'll give on that.

    Chris
    Inspiring
    April 22, 2006
    Do you have an example of how you tested to see if the structure existed or
    not? I was thinking about using structisempty(), but since this is a new
    step for me, just a little confused..

    Thanks for the great long explaination!

    Steve

    "g1zm0guy" <cjordan@placs.net> wrote in message
    news:e2bu4e$8i4$1@forums.macromedia.com...
    > Steve,
    >
    > I've got a program (called AutoEmailer.cfm) that runs every five minutes
    > to
    > send out appropriate emails. The program can be run as a scheduled task,
    > or as
    > a custom tag (to accomplish that task, just check for the existance of the
    > "arguments" structure. If it exists, then it was called as a custom tag.),
    > and
    > when called/run it looks at my email table looking for records with the
    > word
    > "Pending" on them.
    >
    > The rest of the fields contain the information necessary to send that
    > email.
    > AutoEmailer.cfm then generates the necessary emails and sends them out. My
    > table has (among others) the following fields:
    >
    > EmailType
    > EmailStatus
    > UserID (I use this to link to another table that holds the email
    > addresses)
    >
    > So, your program could look for all records where EmailStatus is "Pending"
    > (or
    > something similar), and then generate the appropriate content based on the
    > EmailType (i.e. Renewal, NewUser, DepartingUser,etc.). You could store
    > their
    > email address in this table, or a foreign key to it like I do in my table
    > (UserID).
    >
    > The program would loop over all the records returned by your query. Inside
    > the
    > loop I would create an array of structures. Each array element represents
    > one
    > email, and the structure contained in a single array element would contain
    > things like the address to send it to, the subject the body, etc. It would
    > look
    > something like this:
    >
    > Emails.To = The To Address
    > Emails.From = The From Address
    > Emails.Subject = Some Subject
    > Emails.Body = The Body Of The Email
    >
    > You could add other bits of information like, CC, BCC, FailTo, etc.
    > Whatever
    > you need, but the above should be sufficient for most, you know?
    >
    > Before you start that loop though I would suggest setting the EmailStatus
    > of
    > all returned records to something like "Working" just in case something
    > happens
    > and the emails don't go out as planned. That way the system won't pick up
    > those
    > records on the next go (since their status isn't "Pending" anymore).
    >
    > Then your program would just loop over the number of elements in the
    > Emails
    > array using the information in each structure to populate the different
    > elements of the CFMail tag. Inside this loop you would also set
    > EmailStatus to
    > "Sent" for each record in the table where you've successfully sent an
    > email.
    >
    > I've been using this sort of system and it works quite well. In fact, what
    > I've described is very simple. The system I've got in place is much more
    > complicated, but that is really due to having lots of different EmailTypes
    > and
    > having to fetch Email Addresses in different places depending on what
    > email
    > type it is or what type of recipient I'm sending to. Oy!
    >
    > Anyway, I hope this helps.
    >
    > Chris
    >


    Known Participant
    April 22, 2006
    No sweat, Steve.

    To check for the existance of the structure "arguments" do something like:

    <CFIf ParameterExists(arguments)>
    .... then behave like a custom tag...
    ... the arguments structure can be accessed using standard dot notation...
    <CFElse>
    ... the arguments structure doesn't exist, so behave accordingly...
    </CFIf>

    To would be flamers: I know that ParameterExists is deprecated, but nobody has been able to give me a satisfactory reason for switching to IsDefined.

    Steve, you could also write:

    <CFIf IsDefined("arguments")>

    ... instead of what I gave above. Just note that the latter requires that the argument be passed as a string.

    Read up a bit on structures, they're very handy. I'll give you a very brief overview here.

    If you're creating your own structure do something like this:

    <CFSet MyStructureName = StructNew()>

    ... now you can start adding members to the structure (also called keys)...

    <CFSet MyStructureName.ToList = "usr1@abc.com, usr2@abc.com">
    <CFSet MyStructureName.something = "another structure member">

    This is similar to accessing the coldfusion query object:

    <CFIf QueryName.RecordCount>
    .... then the query returned at least 1 record....
    <CFElse>
    .... no records returned....
    </CFIf>
    The special member "RecordCount" of the structure "QueryName" was zero (0)... I say that this is a special member, because it is one of four structure members or keys, that exist for every query result set that is NOT the name of a column returned by the query. Arguments passed to a <CFFunction> can be handled the same way (...but I digress)


    When the arguments structure DOES exist you'll find that the key name is the variable name and the value of that key is the... well the value. Consider these code snippets:

    <CF_MyCustomTag UserID="12" LoggedIn="true" EmailType="Renewal">

    ... and later, in the custom tag...

    <CFIf Len(Trim(arguments.UserID)) AND Trim(arguments.LoggedIn)>
    .... then the UserID passed wasn't empty and the user was logged in...
    <CFIf Trim(arguments.EmailType) EQ "Renewal">
    .... do whatever to send a renewal letter...
    <CFElseIf Trim(arguments.EmailType) EQ "NewUser">
    .... generate the content of and send out a new user email...
    </CFIf>
    <CFElse> <!--- the userid passed (by you presumably) was empty. Oops! --->
    .... kick 'em to the curb or something...
    </CFIf>

    These are of course loose examples to demonstrate concepts. I hope they help. Again, do a bit of reading on structures they're really cool. I remember having a tough time trying to understand them, but once I had worked enough with them, a light went off in my head and I've loved them ever since. I don't know, maybe you're already comfortable with them.

    If you're talking about an array of structures (structName[1].member1, structname[1].member2, etc.), and you're having trouble visualizing it, try doing <CFDump var="#MyStructureName#"> and take a look at that. I've had arrays of structures in which one or more structure members was another array and that array could possibly had an element whose value is another structure. I'm not saying that is a best practice or anything, but using CFDump helps to visualize some data... in my opinion of course.

    Good luck!
    Known Participant
    April 22, 2006
    Steve,

    I've got a program (called AutoEmailer.cfm) that runs every five minutes to send out appropriate emails. The program can be run as a scheduled task, or as a custom tag (to accomplish that task, just check for the existance of the "arguments" structure. If it exists, then it was called as a custom tag.), and when called/run it looks at my email table looking for records with the word "Pending" on them.

    The rest of the fields contain the information necessary to send that email. AutoEmailer.cfm then generates the necessary emails and sends them out. My table has (among others) the following fields:

    EmailType
    EmailStatus
    UserID (I use this to link to another table that holds the email addresses)

    So, your program could look for all records where EmailStatus is "Pending" (or something similar), and then generate the appropriate content based on the EmailType (i.e. Renewal, NewUser, DepartingUser,etc.). You could store their email address in this table, or a foreign key to it like I do in my table (UserID).

    The program would loop over all the records returned by your query. Inside the loop I would create an array of structures. Each array element represents one email, and the structure contained in a single array element would contain things like the address to send it to, the subject the body, etc. It would look something like this:

    Emails[1].To = The To Address
    Emails[1].From = The From Address
    Emails[1].Subject = Some Subject
    Emails[1].Body = The Body Of The Email

    You could add other bits of information like, CC, BCC, FailTo, etc. Whatever you need, but the above should be sufficient for most, you know?

    Before you start that loop though I would suggest setting the EmailStatus of all returned records to something like "Working" just in case something happens and the emails don't go out as planned. That way the system won't pick up those records on the next go (since their status isn't "Pending" anymore).

    Then your program would just loop over the number of elements in the Emails array using the information in each structure to populate the different elements of the CFMail tag. Inside this loop you would also set EmailStatus to "Sent" for each record in the table where you've successfully sent an email.

    I've been using this sort of system and it works quite well. In fact, what I've described is very simple. The system I've got in place is much more complicated, but that is really due to having lots of different EmailTypes and having to fetch Email Addresses in different places depending on what email type it is or what type of recipient I'm sending to. Oy!

    Anyway, I hope this helps.

    Chris