The future of Family module - Completely Redesigned.
Microbe - March 5, 2008 - 23:35
| Project: | Family Tree 2 |
| Version: | 5.x-3.x-dev |
| Component: | Code |
| Category: | feature request |
| Priority: | normal |
| Assigned: | pyutaros |
| Status: | closed |
Description
can we get a cck development going?
someone suggested we should do this after a port to drupal 6 but im not sure its worth it yet as alot of the modules we mike link it to arnt ported yet like images, timeline, events.
Should it be a new module that is an addon? e.g. a module that requires both cck and family to be enabled
if we are not waiting for the port then i will start some development on this as i think this is quite an important feature.

#1
Microbe,
This doesn't necessarily need to be after the port, but it should be after the relationship linking has been finished. One of the big problems here is that it's going to require us to nearly completely rethink and redesign how we are doing things in this module. This is not something we should rush head forward into.
I do think however that this is a good point to start the conversation. I personally would like to propose a complete evaluation of the existing code, what it currently does, and if there is anything that exists already that does it better. I still would like to hold off on implementing this until 6.x, as it vastly improves the way a lot of things occur, such as dynamic menus.
I am changing the title of this thread to make it clear what we're speaking about. Again, here is what I'm looking for in this discussion:
Please everyone who has an interest in this module, coder or not, chime in and add your opinion. I need to look through the code a bit before I add my thoughts.
Thanks,
Jonathan
#2
the things i think that would be good in future development are:
possibly also a button that appears above or below text boxes from whiuch you can insert a hyperlinked name to reference some in some text - this might need to be controled by another module - e.g. TinyMCE.
linking things to family members (nodes, citations, references etc.) would be alot easier if all the information was linked to the same id (the key in the proposed individuals table) rather than having for example a birth linked to a person then a date linked to the birth a single row should contain the date and the type (birth) and that should be linked to the family_inividual.
i have only been using this module for a sort time and probably dont use it quite as indepth as a geneoagist would so dont know quite what the full protential of this should be or quite what people need so im not sure if my new table idea is practical but it makes more sense to me.
i will look further into what the current citaions, sources and location code does to see if we can use some of it or whether we need to start anew.
hope some of this makes sense im no good at communicating ideas usually
Microbe
#3
Great input Microbe. I'm looking for more of an analysis of where we are, than where we want to go. We already have a wishlist out the wazoo, but no real clear direction or standard on how to implement it. I have to admit I have had a lot of trouble implementing a simple feature such as adding a group content type and the structure for relating it to an individual content type for a few reasons.
Seth has some good documentation at http://famhist.shawspace.com/?q=node/46, which should be considered before I go any further. I am going to review this before I respond any further.
Thanks,
Jonathan
#4
i agree with you there. the most important thing currently is to reorganise the database strucuture. i know from experience that once we choose a layout is it easy to update the code (i can do this once we decide on a strucutre if you feel it would be to hard). i looked at the linked page and still dont think the current setup is at all good, there is way too may querys being run to get all the right information. the GEDCOM standard is just one way of looking at the data and as long as we keep the same variable then we can still convert between the two.
i am thinking currently something like this for column headings:
nid (primary key)
Forenames
Surname
DOB
Place of Birth
DOD
Place of Death
Father nid
Mother nid
Biography text (body - this is probably better left in the node table)
Sources (comma seperated array of nid(key) of sources used)
then a seperate table for marriages e.g.
Family id (unique key)
Husb nid
Wife nid
Date
Place
then a third table for cck relationships between nodes this should be used for linking in images, forums, locations and possibly sources instead of in the first table:
nid of page
nid of family_individual
page type
we do not need the children in this second database as we can get them by searching for the parents nid in the other table.
not sure what other data we want to include but as we have a nid row for each person with the most often used variables we can just link it in using that key like the GEDCOM stucture works.
im not sure how you have done the relationships but using the above tables i think it would be easiest to have on the inividuals page choice of spouse and parents via drop down box or nid number (dropdown boxes could get way to big) children will automatically drop out of adding the parents. just picturing the code in my head makes me think it should be really easy doing it this way.
merge and export are easy to achieve as its just a long list linking variables which we already have linked. merge though is still quite hard as for example we might have two people with the same name and no other data but they must have parents or children to be linked into the tree so we can compare them.
if there are any major bits of information that im missing out on please add them in; obviously if there are variables that need to be added on specifically for certain users of this module they can use stadard cck. otherwise i personally think this would create a great structure.
Microbe
#5
Don't be offended if my next reply says things you've already said above. I've been hashing out the old and new for hours today. No matter what the timestamp says, it was started hours before.
#6
Okay. Let's start with the basics. I'm going to list out the general elements of the module and get a little more granular, including suggestions as to how the structure can be improved. We currently have 12 files and 2 database tables associated with the Family module. Remember, I'm also doing this for my own benefit, so I can get my slow brain around everything. Here is the list (This is also an attempt at adding to documentation.):
Tables
The two tables, facts and relations, work in tandem and so should be addressed together. Seth does a great job explaining them in his documentation, so I will try and avoid being too redundant. The family_facts table is basically a line by line import of a GED file. Most of the fields are always empty, except for some special cases. Also, most fields are only populated by the import, node creation does very little.
The family_facts database has 6 fields: fid, nid, fact_code, xref, fact_value, gedcom_source. I will explain what each of these mean, how we deal with them in our data structure, and what they imply about the overall structure of GEDCOM standard.
I'm going to try and wrap this section up here, both so I can make my point, and so I can read what Microbe wrote above before going on. GEDCOM compliance is VERY important. But not so important that we need to bas our internal Drupal database structure off of it. We need to be aware of the standards so that we can import GED files. We then need to RESPECT the standard when (and if we ever) we export to a file. Anything we do in between is our business in my opinion. That being said, there is a much more effective way of managing all of this, and I will explain exactly how it will work in my next post.
Thanks,
Jonathan
#7
Microbe,
I'm glad you were wrong about your ability to communicate ideas. You've basically gotten at the root of what I'm trying to say here, except that I'm going to take three posts to say it all. I basically agree, but I will explain in my next post.
Thanks,
Jonathan
#8
This next post will focus on how I believe we should implement the database structure going forward for the Family module. First I will take a short while to explain how Drupal does much of the work already for us. Drupal has three main tables which manage node data for us. Again, most of this is for my own benefit, as I am still learning Drupal. I am not going to explain every field.
The first is the NODE table. This table consists of the following fields: nid, vid, type, title, uid, status, created, changed, comment, promote, moderate, sticky. The things of importance to us are the NID and TITLE. It would be good to not here that we could help solve one of our problems with individual identification by implementing a dependancy on the token module. Much like the audio module provides tokens for titling audio nodes, we could provide an admin option to determine the title format. (Examples would be {Firstname} {Lastname} - {Birthdate} OR {Lastname}, {Firstname} - Child of {Familyname}) Once again, let other modules do the work if we can.
The second is NODE_REVISIONS. This table consists of the following fields: nid, vid, uid, title, body, teaser, log, timestamp, format. The one to note here is BODY. This is where the biography information would be contained.
The third is a series of tables by the name of CONTENT_TYPE_XXXX. I have checked against some custom content types I created for another site. Here is an example of what is in the table for one of them: vid, nid, field_genre_value, field_no_of_members_value, field_class_value, field_base_street1, field_base_street2, field_base_apt, field_base_city, field_base_state, field_base_zip, field_base_country, field_base_other, field_status_value.
What you are looking at is a custom set of fields for a custom content type. All of the data is stored directly in the CONTENT_TYPE_XXXX table. This would effectively eliminate the FAMILY_FACTS table and split it's data into content types for each root entity.
Here are the content types I think should be created by our module: Family Individual, Family Group, Family Event (currently just a subfact such as marriage or birth, would require the event module if we want it to display on a calendar, could be implemented with a CCK datefield), and Family Location. Seth may have a better insight on sources and citations and whether they should be nodes or fields. Media doesn't need to be created by our module, as we could use CCK to refer to any media content that the user desires.
Each content type would have it's own set of fields (fields can be shared among types if they are redundant, such as date). At first we may wish to leave events as fields, just to keep this simple. Before I layout the fields for each type, we should take a look at relationships again.
Remember that in GEDCOM standard, no two INDI records link directly to each other. An INDI should always link to a FAM, which in turn links to all of it's related INDI's. I think we could accomplish this by using one of the following CCK add-ons and modifying slightly to cause a two-way relationship. Relationships to facts would be eliminated as they would be contained directly in the CONTENT_TYPE_XXXX table as a field. Finally, relationships to media could be established as a one way relationship from a family node to a media node using one of these same CCK add-ons. Here they are: Addnode, Enhanced Nodereference Autocomplete Widget, Hierarchical Select Description, Multiselect, Node factory, Textfield Autocomplete.
Finally, here are my proposals for the field layout of each content type:
I think a picture should be forming here that we'd basically be completely eliminating both of our current database tables. The next thing that needs to be examined, is how much of our existing code is worth saving as we adopt a totally new structure. I think it would be rather courteous of us to complete an export to GED file feature before we make this huge jump. On the other hand, since our current format hasn't really been creating GEDCOM compliant content anyhow, any additions made in Drupal so far would create junk in the output. I'm going to end here for now, and discuss code in my next post.
Thanks,
Jonathan
#9
Oops, i did write a long comment but seems i closed the page by accident, anyway here will be a shortened version as i can't be bother to write it all again.
will we be able to add places without refernceing a location node with the above setup?
i think media should be referenced the other way round - link the media to the person using one of the above suggested modules(i will look at them and check to see which one i think is best and make a vote). if we have one of these as a required module we can include a viewing page that lists all media linked to that family individual.
father / mother should be in the group table not as 'parent of family' in the individual table as they might be a parents of multiple families. this would also mean you would not need a cck module to link the pages which would make things even more complicated than they are currently.
i dont think we need the '# of children' entry either as this could be calculted by doing a query then counting the rows. also this would be hard to update as like you have also said above the parents don't directly link to children.
apart from the above to points i think Jonathan's table structures are a good way to go
GEDCOM export would as u say be a lot of time wasted although we do need to allow people to easily update to the new table version so i think it should be a conversion of the import script in the update script that needs to be run when modules are updated.
finally i think we should port to drupal 6 at the same time as doing all of this. by the time this massive change is done it should have good support from other modules that do not currently have a drupal 6 version.
i think this was all i had said before
Microbe
P.S. noticed that there is an error in that when you edit an individual the title of the node is still what the name was before it was changed, if i then change it again it changes to the first time i changed it rather than the third. its always one behind. didn't think this was important enough to post a new issue as its only reordering the code (i think).
#10
i looked at those modules for use with realting media(images and forums) to family individuals and i have found that it is really good to use either Enhanced Nodereference Autocomplete Widget or Multiselect These do the same thing in different ways so either could be used - i think the autocomplete one is better though for bigger databases though (also if you have multiple people with the same name as it also shows the nid value). I added this field to the image page and put hidden on displaying it.
Then i used a module which you haven't already referenced, Node Referrer. This module creates a list of nodes referenced to a certain node (the node this cck field is added too). I added this to the family_individual node. this then creates a nice setup for easily referencing images and such to family members. i think it is better to have the referencing it this way round because images and other media are probably going to be added more often than new family members.
This module doesn't however display the images as thumbnails so maybe we should create new module very closely based on this module that does.
All this would mean we wouldn't need to worry about media in our database. We dont even need worry about it but just add into our documentation that something like this is a recommended plan of action.
We could use this also link in the locations except the locations being referred to (thinking about this it would be hard to do as it would not link properly into the GEDCOM).
What we really need to do is create a profile that setups the cck fields on drupal install.
Microbe
#11
Thanks for all the good research here Microbe. Before we go ahead with all of this, I'd still like to give Seth and Pfolk a chance to chime in. I'd also like to keep your enthusiasm going here, so I don't want to wait too long. I'm not certain if they're still working on this, so I think two days might be appropriate. In the meantime, I'd like to discuss the module files and how they'd be affected by this new structure. In some cases it may make sense to start fresh. In others, we may wish to recycle bits of code.
Let me review, once again for my own sake. Here's the general Structure that we've discussed so far.
I think we can have a functioning module by #3. Those seem like CORE features. The rest are ADD-ON's IMO. I'm sure I'm leaving things out. Let me know what you think Microbe, especially about the order of taking on these tasks. 1, 2, 4, and 5 are my specialties, as they're not too complex, and I'm very anal about sticking to Drupal standards. I'm also very interested in learning how to create fields through module declarations. All I've done in the past is manually create fields and nodes. And please, anyone else, feel free to offer up opinions. Oh, and one final question... Drupal 5 or 6? If we go with 6, we could be waiting till May for CCK to be available, let alone all of the add-ons that we're going to depend on.
#12
i think you've got most of this sussed out. i think drupal 5 is still the one to go with. we still have about another year before people start to stop using it.
i like you idea for the location addnode.
should there be any media entries? shouldn't they all reside with the media content so they can be added simultaniously - refer to individuals and groups and locations if need be.
could we also add 'related locations' for locations that arn't DOB DOD or marriage but are associated with the individual e.g. houses they lived in.
yes, it would only be minor modifications for the tree.inc file - alot of what it does is use other functions so they would be easy to change. however, i feel the hook functions might be best to redoo almost completely only keeping the current ones as a template rather than just editting them. if the family module is going to be really good by the end of this everything needs to use the new implemntations rather than just changing a few things from the old.
how do we create the view of the list of family members whilst installing the module, if you know how to do it that is great.
because alot of the fields we will use will be cck how do we implement them so that we use them but put the data into our own database? is it just like type='nodereference' or similar?
i think maybe privacy should be higher up the priorities because that means people can put their site online early on and the script shouldn't be too hard to change.
it would be nice i think if rather than a tab for the tree there was like a small link in the top right of the page. like ASC - DESC with a little button picture for each. this is just a very minor point though. that will probaly be better answered when we get to implementing it.
permissions should be at the top of our priorities as alot of the priorities are assigned as we go along. we shouldn't spend a long time on them but we should define them and then apply them as we create nodes. i think basically like you said the top 5 items will probably not be in any order but just all come together when they are ready - they all sort of 'require' each other.
how will we deal out things to get this project going? i think its probably best if you create the permissions and all the install files and then everyone who wants to help can work on separate nodes maybe? im not sure how this would work though. alot of the starter stuff needs to be well colaborated and we could end up in a mess if we dont organise it properly.
extra modules that could help that i found:
everything else i think is great. lets just wait for some other replies and get started.
#13
forgot to add - can we release a new version as it is with you groups implemented? im sure this would be useful to alot of people and i know you've spent a long time on it so there no point it going to waste.
#14
Quick replies / comments:
Explain what you meant here. I just want a way for images to display on an individual's page. Just a single image actually. Same for groups and locations. I was thinking the way to do this was node referral. Attach the media from a custom media node and then be able to see it from the referred node.
This is a good idea. I'm uncertain on the specific implementation. I'm thinking this is how a Family_event would work. (i.e. Nov 2008, moved to Ohio) We could also try something like image attach. (Location Attach?)
Don't know yet. I know other modules do it. It is one of my top priorities. Luckily Views has excellent documentation available.
Once again, don't know, but I know that's part of it. I believe you actually have to create the field somewhere in your module. As you may or may not know, CCK field building goes as follows: A module (or other customized code) makes a field type available, you then create a field that uses that type with specified parameters, you then include that field in one ore more node types.
I am impartial. Or in other words, sounds okay to me.
I still say tabs. There is a hook for it (hook may not be the right word) and it is the Drupal way.
Thursday, I will create our final game plan, based on what we've discussed. I'm spending some time thinking about this to get the right attack. If you think you'd be comfortable altering the privacy routines, I'd suggest you start looking at it. Or even better, I'm basically stuck in my efforts to finish the original plan to implement relations under the old structure. If you'd feel comfortable picking that up, I can show you exactly where I'm at and what was giving me the problem. It is basically incomplete as it stands now and wouldn't do anyone a lot of good. It wouldn't be the first time I worked hard at doing something the wrong way, then finally threw it out and did it the right way.
#15
Wow. Views implementation is super easy. There's a views hook views_default_views, within which you paste the exported code from a view. Super simple. CCK implementation seems a little bit more complicated. We may be better off creating the tables we discussed in our own space per node (i.e. family_individual). I don't know. I still need to read up more on this one. I was wrong about other modules. Every module I have installed that creates a node type is doing this through hook_node_info, hook_form, and hook_view. At least Views was good news. I suppose what we could do within our module related to CCK is declare the fields ourselves, rather than having the user have to install all of these dependent field types. More on this later.
#16
to be honest i don't think the cck is a good idea either. it means the are alot of modules that need to be compatible.
i didn't mean work on the privacy quite that quickly - it should be after we have created the install profile and after we have created basic nodes, otherwise there is nothing to test against.
so far no one else has contributed so it looks like it could be just you and me for the time being. i think the project should be 'family tree 2' module that can run along side the current one. no need to work on the transfer odf information at the moment then (dont mean start a new project on drupal just call it that in the .info file so they are seperate).
to-do list
others things like implementing menus for example should be done as we go along
anybody can put there name to a numbered item in the list where it still has anyone written their if they want to contribute. personally i would like to get involved as much as possible but i don't think people can work on this first section simulatneously (creaing nodes and views) so i think it best that either one person does it all or we pass it round (or if there is two of us back and forth) - i have noticed that you always post during my night time so maybe we could in tandem updating at the end of eaches day.
not sure if this would work though? I am going to bed now and my period of free time to spend on drupal is in the last 6 hours (not all though). no point givine times cos im guessing they show differently on ur drupal view as the time is setup differently. if you period of time is after this then we can swap, probably not a good idea though as it would get confusing, see what you think
#17
Microbe,
Let's divide up tasks, rather than pick up after each other. I can be a little sporadic about timing anyhow. I will start yet another branch - 5.x-3.x-dev - so that the previous version will be preserved for reference. I am considering this new version to be completely incompatible with previous versions. I will try and document as I go along in the README. Users will be advised to completely uninstall the old version before installing the new one. I will include instructions in the README on what to check for. I will create the new .install file, .info file, and begin working on the new .module file. I will make the declarations for all three content types at once, but will only do the form for Individual. Once I've got the first content type accepting data and updating the database, I will create the view. I will try and get started on this right away. I'll post updates here.
Thanks,
Jonathan
#18
BTW - I'm in EST time.
#19
I forgot to mention token declaration. That needs to happen before I create the nodes.
#20
Ok so quite alot to do!
Is there anytihng u would like me to do while you setup all the nodes and things?
#21
Sorry for the delay. I think you should be able to get away with constructing the bones of the node view pages. I will be using family_individual, family_location, and family_group for the node type names. The Drupal hook involved with this is hook_view. The branch has been created. You can now download from CVS. .info file now says Family Tree 2.
#22
I had delayed actually completing the .install file until I knew whether the Drupal database abstraction layer was capable of creating tables. It is not, so I will retain the same SWITCH structure it previously had. Good news for porting to Drupal 6. Table creating is implemented in the DBAL for Drupal 6. More updates to come.
#23
Got the first table into the database. family_individual. Also documented each field, though it is mostly self explanatory. It doesn't do anything yet. The new code is still commented out. Here is how the table will be created for MySQL:
CREATE TABLE `testlab5_drupal`.`family_individual`(`vid` INT(10) UNSIGNED NOT NULL DEFAULT '0',
`nid` INT(10) UNSIGNED NOT NULL DEFAULT '0',
`title_format` VARCHAR(128) CHARACTER SET utf8 COLLATE utf8_general_ci NULL,
`firstname` VARCHAR(128) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT 'Unknown',
`middlename` VARCHAR(128) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT 'Unknown',
`lastname` VARCHAR(128) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT 'Unknown',
`gender` SET('F','M') NOT NULL,
`birthdate` DATE NULL,
`birthplace` VARCHAR(128) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT 'Unknown',
`deathdate` DATE NULL,
`deathpace` VARCHAR(128) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT 'Unknown',
`children_num` INT(10) UNSIGNED NULL DEFAULT '0',
`ancestor_group` VARCHAR(128) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT 'Unknown',
`descendent_group` VARCHAR(128) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT 'None',
`media` VARCHAR(128) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT 'None',
Some fields were put in more as placeholders than as functioning parts. They will be easy enough (and exciting for me) to remove with hook_update if we decide.
#24
kool thats quite quick work.
you mentioned creating the view for the nodes - how do we want these to look? should they be similar to how they already are or should they be different? if so how do you think they can be imporved?
#25
oops double posted
#26
The view that we currently have is good, but it doesn't address three things that we have talked about:
For descendancies, we currently refer to the partner as a spouse, but this is inaccurate for unwed partnerships. I like how we currently list the partner, but do we need to include all of their information? Perhaps just their name, gender, birthdate, and deathdate then the list of children. I do like how we currently list the children. We need to add a field in the table for middle name.
The media object would just be a thumbnail of the media that references the person. Off to the side from the person's information. Maybe a look at the audio module would be good here as they show an album art picture next to the song info.
The separate fields for place and date is self explanatory. I can create with a mock up if you like, or if you'd like to make a mock up that would be great too. I will have the other database tables created by the end of the day.
Thanks,
Jonathan
#27
I like your points. i think it should just be name, gender, and group info (marriage, divorce, widowed - this should also be added to the group page as separate field or choose split up type field). i dont think middle names should show of children and spouses on these pages as they make names too long.
Answers to the issues
It does already do this - i have a family on my website where there are two spouses both with children. this works ok apart from one child appears in both sections (checked the database and its correct). but this will probably correct with new databases.
I think the answer to this is to use node reference on the media pages like i said (e.g. image/forum) and then use a edited node referrer (family media referrer). I will have a look at the audio module and see if i can get a gallery of the images. it might also help looking at image gallery module too. if neither look like they can be used ill create something myself. i have attached what i'm currently doing on my site for media content (or you can view it here: http://familytree.itzalive.co.uk)
as you said this is obvious and is really easy
i will try creating the form page at the same time and see if it works with the new database
#28
Finished the install file. Here is the complete code. It has been committed to development branch 5.x-3.x-dev.
// $Id: family.install,v 1.1.2.5.4.1.2.2 2008/03/16 19:08:17 pyutaros Exp $
/* ---------------------------------
-- FAMILY_INDIVIDUAL
-- vid: vocabulary id? (PRIMARY)
-- nid: node id (PRIMARY)
-- title_format: contains the specified format for concetenating tokens
-- firstname: the individual's first name
-- middlename: the individual's middle name
-- lastname: the individual's birth surname
-- gender: acceptable values are M or F
-- birthdate: the individual's date of birth
-- birthplace: the individual's place of birth (This will eventually be a reference to the location node)
-- deathdate: the individual's date of death
-- deathplace: the individual's place of death (This will eventually be a reference to the location node)
-- children_num: the number of children that an individual has (this is be a stored calculation, so it doesn't have to be figured every time the node is viewed)
-- ancestor_group: the family an individual is a child of (This will eventually be a reference to the group node)
-- descendent_group: NOT A FIELD - Identified by querying GROUP node's 'parent1' and 'parent2' fields for a match.
-- media: a picture, video or audio of the individual (This will eventually store a list of all media that link to the individual node)
-- FAMILY_GROUP
-- vid: vocabulary id? (PRIMARY)
-- nid: node id (PRIMARY)
--title_format: contains the specified format for concetenating tokens
--marr_type: The type of union between parents (Currently only accepts unmarried and religious)
--marr_date: Date of declared union if any
--marr_plac: The place of union if any official partnership was declared
--div_date: Date the union was nullified.
--div_plac: Location of nullification the union (could be a courthouse, or just the place the couple was living at the time)
--parent1: Parent of the family (Gender neutral field. Will be a referral to an individual node, containing that node's nid)
--parent2: Parent of the family (Gender neutral field. Will be a referral to an individual node, containing that node's nid)
-- media: a picture, video or audio of the group (This will eventually store a list of all media that link to the individual node)
--CHILDREN of a group are identified by querying an INDIVIDUAL node's 'ancestor_group' field for a match.
FAMILY_LOCATION
-- vid: vocabulary id? (PRIMARY)
-- nid: node id (PRIMARY)
--title_format: contains the specified format for concetenating tokens
--building: If the location is not a residence, the name of the location (i.e. Springfield County Courthouse)
--street: Street address
--city: Name of the city
--county: Name of county if one exists
--state_province: Name of state or province
--country: Name of country
-- media: a picture, video or audio of the location (This will eventually store a list of all media that link to the individual node)
------------------------------------ */
function family_install() {
switch ($GLOBALS['db_type']) {
case 'mysql':
case 'mysqli':
db_query("
CREATE TABLE `family_individual`
(`vid` INT(10) UNSIGNED NOT NULL DEFAULT '0',
`nid` INT(10) UNSIGNED NOT NULL DEFAULT '0',
`title_format` VARCHAR(128) CHARACTER SET utf8 COLLATE utf8_general_ci NULL,
`firstname` VARCHAR(128) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT 'Unknown',
`middlename` VARCHAR(128) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT 'Unknown',
`lastname` VARCHAR(128) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT 'Unknown',
`gender` SET('F','M') NOT NULL,
`birthdate` DATE NULL,
`birthplace` VARCHAR(128) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT 'Unknown',
`deathdate` DATE NULL,
`deathpace` VARCHAR(128) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT 'Unknown',
`children_num` INT(10) UNSIGNED NULL DEFAULT '0',
`ancestor_group` VARCHAR(128) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT 'Unknown',
`media` VARCHAR(128) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT 'None',
PRIMARY KEY ( `vid` , `nid` )
) ENGINE = MYISAM ;
");
db_query("
CREATE TABLE `family_group` (
`vid` INT( 10 ) UNSIGNED NOT NULL DEFAULT '0',
`nid` INT( 10 ) UNSIGNED NOT NULL DEFAULT '0',
`title_format` VARCHAR( 128 ) CHARACTER SET utf8 COLLATE utf8_general_ci NULL ,
`marr_type` SET( 'Unmarried', 'Religious' ) NOT NULL ,
`marr_date` DATE NULL ,
`marr_plac` VARCHAR( 128 ) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT 'Unknown',
`div_date` DATE NULL ,
`div_plac` VARCHAR( 128 ) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT 'Unknown',
`parent1` VARCHAR( 128 ) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT 'Unknown',
`parent2` VARCHAR( 128 ) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT 'Unknown',
`media` VARCHAR( 128 ) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT 'None',
PRIMARY KEY ( `vid` , `nid` )
) ENGINE = MYISAM
");
db_query("
CREATE TABLE `family_location` (
`vid` INT( 10 ) UNSIGNED NOT NULL ,
`nid` INT( 10 ) UNSIGNED NOT NULL ,
`title_format` VARCHAR( 128 ) CHARACTER SET utf8 COLLATE utf8_general_ci NULL ,
`building` VARCHAR( 128 ) CHARACTER SET utf8 COLLATE utf8_general_ci NULL ,
`street` VARCHAR( 128 ) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT 'Unknown',
`city` VARCHAR( 128 ) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT 'Unknown',
`county` VARCHAR( 128 ) CHARACTER SET utf8 COLLATE utf8_general_ci NULL ,
`state_province` VARCHAR( 128 ) CHARACTER SET utf8 COLLATE utf8_general_ci NULL ,
`country` VARCHAR( 128 ) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT 'Unknown',
`media` VARCHAR( 128 ) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT 'None',
PRIMARY KEY ( `vid` , `nid` )
) ENGINE = MYISAM
");
break;
}
}
function family_uninstall() {
db_query('DROP TABLE {family_individual}');
db_query('DROP TABLE {family_group}');
db_query('DROP TABLE {family_location}');
db_query("DELETE FROM {variable} WHERE name LIKE 'family_%'");
$q = db_query("select nid from {node} where type = 'family_individual'");
$n = 0;
while ($o = db_fetch_object($q)) {
node_delete($o->nid);
$n++;
}
drupal_set_message(t('Deleted @n family_individual nodes.', array('@n' => $n)));
$q = db_query("select nid from {node} where type = 'family_group'");
$n = 0;
while ($o = db_fetch_object($r)) {
node_delete($o->nid);
$n++;
}
drupal_set_message(t('Deleted @n family_group nodes.', array('@n' => $n)));
$q = db_query("select nid from {node} where type = 'family_location'");
$n = 0;
while ($o = db_fetch_object($r)) {
node_delete($o->nid);
$n++;
}
drupal_set_message(t('Deleted @n family_group nodes.', array('@n' => $n)));
}
#29
two things:
#30
Finished the major edits to family.module today. I think some of the menu items we had before for the nodes were unnecessary. At least api.drupal.org doesn't mention the need for these menu items in node declaration. I have commented out all lines calling for include files for now. I created a new file for locations called location.inc. I also completely wiped group.inc and individual.inc and put a skeleton structure in place that I will fill in as I go. Here is the full text of the node .inc files . I will post the full code for family.modules at the end of this post.
<?php
/**
* Implementation of hook_form().
*/
function family_group_form(&$node) {
} // function family_group_form(&$node, &$param)
/**
* Implementation of hook_insert().
*/
function family_group_insert($node) {
} //function family_group_form()
/**
* Implementation of hook_load().
*/
function family_group_load($node) {
} //function family_group_load()
/**
* Implementation of hook_update().
*/
function family_group_update($node) {
} //function family_group_update()
/**
* Implementation of hook_view().
*/
function family_group_view(&$node, $teaser = FALSE, $page = FALSE) {
} //function family_group_view()
/**
* Implementation of hook_delete().
*/
function family_group_delete(&$node) {
} //function family_group_delete
You can see that each node type while be declaring these hooks separately in the form of 'module name'_'node type'_hook. This was specified in hook_node_info in family.module per node type. Also, hook_access was removed from the include files and placed back in family.module as the behavior is the same regardless of node type. The hooks currently in the includes are form, insert, load, update, view, and delete. The only ones that aren't here (and weren't previously) are nodeapi, validate, and theme_node_example_order_info. I'll see if any of these are really necessary. Now that all three .incs exist and most of the structure is in place, we can divide these files up and fill the functions in. I'll go ahead and take group.inc. If you would take individual.inc when you have time, I would greatly appreciate it. That's all for today. All changes have been committed.
<?php
// $Id: family.module,v 1.8.4.5.2.3 2008/03/04 05:29:15 pyutaros Exp $
/**
* @file
* Family module - display and manage family tree data
*
* Current features:
* - Individuals saved as nodes
* - Editing for Individuals records
* - Groups saved as nodes
* - Editing for Groups records
* - Locations saved as nodes
* - Editing for Locations records
*/
$path = drupal_get_path('module', 'family');
// require_once "$path/import.inc";
// require_once "$path/view.inc";
// require_once "$path/EstimateDates.inc";
// require_once "$path/common.inc";
// require_once "$path/individual.inc";
// require_once "$path/location.inc";
// require_once "$path/source.inc";
// require_once "$path/group.inc";
// require_once "$path/tree.inc";
/**
* Implementation of hook_menu().
*/
function family_menu($may_cache) {
$items = array();
if ($may_cache) {
/** $items[] = array(
* 'path' => 'node/add/family_individual',
* 'title' => t('Family: Individual'),
* 'access' => user_access('create family nodes')
* );
* $items[] = array(
* 'path' => 'node/add/family_group',
* 'title' => t('Family: Group'),
* 'access' => user_access('create family nodes')
* );
* $items[] = array(
* 'path' => 'node/add/family_location',
* 'title' => t('Family: Location'),
* 'access' => user_access('create family nodes')
* );
* $items[] = array(
* 'path' => 'family',
* 'title' => t('Family'),
* 'callback' => 'family_view_record',
* 'type' => MENU_ITEM_GROUPING,
* 'access' => user_access('access family nodes'),
* );
* $items[] = array(
* 'path' => 'admin/content/family_import',
* 'title' => t('Family Import'),
* 'description' => 'Import your family tree from a standard GED file.',
* 'callback' => 'family_import',
* 'access' => user_access('administer family'),
* );
* $items[] = array(
* 'path' => 'admin/settings/family_privacy',
* 'title' => t('Family Privacy Settings'),
* 'description' => 'Protect living relatives with auto privacy.',
* 'callback' => 'family_auto_privacy',
* 'access' => user_access('administer family'),
* );
* $items[] = array(
* 'path' => 'admin/settings/family_privacy_done',
* 'title' => t('Auto Privacy Done'),
* 'callback' => 'family_auto_privacy_done',
* 'type' => MENU_CALLBACK,
* 'access' => user_access('administer family'),
* );
* $items[] = array(
* 'path' => 'admin/content/family_import_done',
* 'title' => t('Import Done'),
* 'callback' => 'family_import_done',
* 'type' => MENU_CALLBACK,
* 'access' => user_access('administer family'),
* );
* $items[] = array(
* 'path' => 'family/view',
* 'title' => t('Index'),
* 'callback' => 'family_view_record',
* 'access' => user_access('access family nodes'),
* );
* $items[] = array(
* 'path' => 'family/view/source',
* 'title' => t('View Source'),
* 'callback' => 'family_view_source',
* 'type' => MENU_CALLBACK,
* 'access' => user_access('access family')
* );
* $items[] = array(
* 'path' => 'family/view/citation',
* 'title' => t('View Citation'),
* 'callback' => 'family_view_citation',
* 'type' => MENU_CALLBACK,
* 'access' => user_access('access family')
* );
* $items[] = array(
* 'path' => 'family/tree',
* 'title' => t('Family Tree Diagrams'),
* 'callback' => 'family_view_tree',
* 'access' => user_access('access family'),
* );*/
return $items;
}
} // function family_menu()
/**
* Implementation of hook_info().
*/
function family_node_info() {
return array(
'family_individual' => array(
'name' => t('Family: Individual'),
'module' => 'family_individual',
'description' => t('A node representing a person.')
),
'family_group' => array(
'name' => t('Family: Group'),
'module' => 'family_group',
'description' => t('A node representing a single grouping of parents and children.')
),
'family_location' => array(
'name' => t('Family: Location'),
'module' => 'family_location',
'description' => t('A geneological location.')
),
);
}
/**
* Display help and module information
* @param section which section of the site we're displaying help
* @return help text for section
*/
function family_help($section='') {
$output = '';
switch ($section) {
case "admin/modules#description":
$output = t("A complete archiving system for socio-historical data.");
break;
case "admin/modules#description":
$output = t("A jolly exciting module for recording and archiving all
aspects of your family's history.");
break;
case "node/add#family_individual":
$output = t("A record of a single person. Part of the Family module.");
break;
case "node/add#family_group":
$output = t("A record of a single grouping of parents and their children. Part of the family module");
break;
case "node/add#family_location":
$output = t("A record of a single location, which may be contained
in other locations in a hierarchy. Part of the Family
module.");
break;
}
return $output;
} // function family_help($section='')
/**
* Implementation of hook_perm().
*/
function family_perm() {
return array(
'access family nodes',
'access family private records',
'create family nodes',
'edit family nodes',
'edit own family nodes',
'administer family'
);
} // function family_perm()
/**
* Implementation of hook_access().
*/
function family_access($op, $node) {
global $user;
if ($op == 'create') {
return user_access('create family nodes');
}
if ($op == 'update' || $op == 'delete') {
if (user_access('edit own family nodes') && ($user->uid == $node->uid)) {
return TRUE;
}
if (user_access('edit family nodes')) {
return TRUE;
}
}
if ($op == 'view') {
return (user_access('access family nodes');
}
} // function family_access()
/**
* Implementation of hook_user().
*/
function family_user($op, &$edit, &$account, $category = NULL) {
switch ($op) {
case ('insert'):
case ('update'):
case ('submit'):
case ('login'):
case ('logout'):
case ('delete'):
break;
case ('form'):
if ($category == 'account') {
$form['family'] = array(
'#type' => 'fieldset',
'#title' => t('Family association'),
'#collapsible' => TRUE,
'#weight' => 4);
$form['family']['family_link'] = array(
'#type' => 'textfield',
'#title' => t('My family link'),
'#default_value' => $edit['family_link'],
'#description' => t('The node number for the family_individual that represents you.'));
$form['family']['family_tree_root'] = array(
'#type' => 'textfield',
'#title' => t('Tree root individual'),
'#default_value' => $edit['family_tree_root'],
'#description' => t('The node number for the family_individual that your default tree is based on.'));
$form['family']['family_tree_type'] = array(
'#type' => 'select',
'#options' => array(
'ANS' => 'Ancestry',
'DESC' => 'Descendency',
'PED' => 'Pedigree',
),
'#default_value' => $edit['family_tree_type'],
'#description' => t('The type of tree you prefer to see by default.'));
$form['family']['family_tree_depth'] = array(
'#type' => 'textfield',
'#title' => t('Tree depth'),
'#default_value' => $edit['family_tree_depth'],
'#description' => t('The number of degrees to show on your default family tree.'));
}
return $form;
case ('view'):
return array(
t("Family Association") => array(
array('title' => t("My family link"), 'value' => l("Me","node/".$account->family_link)),
# description => t('The node number for the family_individual that represents you.'));
array('title' => t("Tree root individual"), 'value' => l("root","node/".$account->family_tree_root)),
# description => t('The node number for the family_individual that your default tree is based on.'));
array('title' => t("Tree type"), 'value' => $account->family_tree_type),
# description => t('The type of tree you prefer to see by default.'));
array('title' => t("Tree depth"), 'value' => $account->family_tree_depth),
# description => t('The number of degrees to show on your default family tree.'));
));
}
}
#31
@ 29
1) Thanks. Good catch.
2) Not sure. Probably some edits I made in 5.x-2.x-dev. I've been developing from two different machines, and probably hadn't synched up. Either way. From taking a quick look at view.inc, I can tell you that most if not ALL of it will be going away in this new version.
Thanks,
Jonathan
#32
luckily i have already started work on individual (luckily in that i could have done a different page). thanks for the new module file.
i have also noticed that 'deathplace' in the individuals database is written 'deathpace' (no L)
let you know if and when i spot other mistakes
#33
I have found that when the database you using has a prefix the install doesn't use the prefix so doesn't work. this is because you haven't put {} arounf the table name.
also add ? to gender so it can remain unknown as previously or is it just left blank if unknown?
#34
Corrected deathpace to deathplace.
Added {} to all tablenames in install.
Added '?' to gender.
Committed all.
#35
i have done the individual page and some other stuff
if you can't see the view it does - same columns as before (lastname, firstname, middlename, gender, birthdate, deathdate) the pager works (i believe) and you can sort it by lastname, firstname, birthdate and deathdate. Any help on getting this to always work would help as i dont know where to go from here.
also i dont know how to add this view as the menu item so this could be useful to look at too
i have attached all the files I've changed now as they all have changed slightly (i think).
Pics for the tree are the same as previous release (asctree.png, left.png, right.png center.png, single.png)
#36
Excellent work Microbe. I'm afraid I've fallen a little behind you in my efforts. Hopefully I'll have group.inc completed no later than Thursday. If you start to get really bored, you could tackle location.inc as well. It occurs to me that I don't have all these other PNG files you refer to committed to the 5.x-3.x-dev branch. Could you repost those? Also, would it put you out too much if I put them in a subdirectory? I think the only file we'd have to update is family.module, but I could be wrong. I'll take a look at all those other issues you mentioned upon completion of group.inc.
Thanks again,
Jonathan
#37
Sorry I missed post #27. I agreed with most everything anyhow. As far as media goes... Can we do both? In other words, showing all related media as a list is great. I think it would be cool if we could then select one of those in the list and make it the primary media for the node. What I'm describing might be a feature for down the road. What you have is definitely sufficient. Would we need to implement hook_nodeapi to add the node reference to image node type?
I really like what you've done on your site. I especially like your custom front page. Very cool. Anyhow, just wanted to mention that while I thought of it. BTW do you Skype? Send me info to my contact page if you do. I also have an Ekiga account. (SIP)
#38
One more thought on media, should we dump all the referrals into a table to speed up page load times? In other words, it would definitely be faster to query a table of referrals than to query EVERY media node to see if it references the current node. Let me know what you think.
#39
Oh and one more thing, did you find it was necessary to redeclare hook_access per node type, or is one declaration in family.module sufficient?
#40
I also noticed in individual.inc the following lines (Sorry for the continuous BTW's):
$form['BIRT']['DEAT_DATE'] = array('#type' => 'textfield',
'#title' => t('Death Date'),
'#description'=>t('Year-Month-Day YYYY-MM-DD'),
'#default_value' => $node->DEAT_DATE,
);
$form['DEAT']['DEAT_PLAC'] = array(
'#type' => 'textfield',
'#title' => t('Death Place'),
'#default_value' => $node->DEAT_PLAC,
);
Just wanted to see if it was intentional.
#41
Okay, last BTW. I committed all of your changes to CVS. I finished group.inc's hook_form. I pretty much copied your code and customized for my fieldset. One thing that we are not doing yet I believe is that we are not "tokenizing" <== My made up word. I plan on implementing that after the node types are complete. The point of including tokens is so that node Title concatenation goes into the hands of the user. In other words, if they want {firstname} {lastname} or {lastname} {birthdate} or {firstname} {middlename} {lastname} {birthdate}, all they have to do is enter those tokens in the Title (actually title_format) field. This is definitely something we can implement after the fact. Also, declaring tokens will help us play nice with Pathauto, which many folks choose to use. Anyhow, here is the code for family_group_form. I'm obviously struggling with how to describe a union without calling it a marriage. Also, when looking over the divorce (separation) section, it occurred to me that we don't cover the scenario of death in marriage. Maybe we should also have a field of divorce_type. Thanks again for your work. The dev tarball is finally available here. NOTE - It only updates once every 12 hours.
/*** Implementation of hook_form().
*/
function family_group_form(&$node) {
$form['title'] = array(
'#type' => 'hidden',
'#default_value' => $node->NAME,
);
$form['MARR']['MARR_TYPE'] = array(
'#type' => 'select',
'#title' => t('Type of Union'),
'#default_value' => $node->MARR_TYPE,
'#options' => array(
'Unmarried' => 'Unmarried',
'Religious' => 'Religious',
);
$form['MARR']['MARR_DATE'] = array(
'#type' => 'textfield',
'#title' => t('Date of Union'),
'#description'=>t('Year-Month-Day YYYY-MM-DD'),
'#default_value' => $node->MARR_DATE,
);
$form['MARR']['MARR_PLAC'] = array(
'#type' => 'textfield',
'#title' => t('Place of Union'),
'#default_value' => $node->MARR_PLAC,
);
$form['MARR']['DIV_DATE'] = array(
'#type' => 'textfield',
'#title' => t('Date of Separation'),
'#description'=>t('Year-Month-Day YYYY-MM-DD'),
'#default_value' => $node->DIV_DATE,
);
$form['MARR']['DIV_PLAC'] = array(
'#type' => 'textfield',
'#title' => t('Place of Separation'),
'#default_value' => $node->DIV_PLAC,
);
$parents=array();
$indivs=db_query('SELECT nid, title_format FROM {family_individual}');
while($data = mysql_fetch_array($indivs)){
$parents[$data['nid']]=$data['title_format'];
}
$form['PAR1'] = array(
'#type' => 'select',
'#title' => t('Parent 1'),
'#default_value' => $node->PAR1,
'#options'=> array('' => 'Unknown', 'Individuals'=>$parents),
);
$form['PAR1'] = array(
'#type' => 'select',
'#title' => t('Parent 2'),
'#default_value' => $node->PAR2,
'#options'=> array('' => 'Unknown', 'Individuals'=>$parents),
);
$form['body_filter']['body'] = array(
'#type' => 'textarea',
'#title' => t('Biography'),
'#default_value' => $node->body,
'#rows' => 20,
'#required' => FALSE,
'#weight' => 2
);
$form['body_filter']['format'] = filter_form($node->format); //Not sure why this goes here, but all the examples have it...
return $form;
} // function family_group_form(&$node, &$param)
#42
Okay group.inc is mostly completed. All hooks have been implemented. I started on the theme functions, but that took me into view.inc, and that made my head start spinning. I trudged through 3 levels of callbacks and decided midnight was not the time to start this task. Here is the code from group.inc, followed by what I added to view.inc. I'm sure if you download these files from CVS, you are going to get massive errors about calls to undefined functions. Also, I implemented hook_load in a slightly different fashion. All this code has given me many ideas on how to change things here and there (like using vid instead of nid, implementing token functions to build names), but I'd rather get a working prototype before I start tweaking. If you or I can get this View function completed, I think we'll be well on our way to completing that. Without further ado...
<?php
/**
* Implementation of hook_form().
*/
function family_group_form(&$node) {
$form['title'] = array(
'#type' => 'hidden',
'#default_value' => $node->NAME,
);
$form['MARR']['MARR_TYPE'] = array(
'#type' => 'select',
'#title' => t('Type of Union'),
'#default_value' => $node->MARR_TYPE,
'#options' => array(
'Unmarried' => 'Unmarried',
'Religious' => 'Religious',
);
$form['MARR']['MARR_DATE'] = array(
'#type' => 'textfield',
'#title' => t('Date of Union'),
'#description'=>t('Year-Month-Day YYYY-MM-DD'),
'#default_value' => $node->MARR_DATE,
);
$form['MARR']['MARR_PLAC'] = array(
'#type' => 'textfield',
'#title' => t('Place of Union'),
'#default_value' => $node->MARR_PLAC,
);
$form['MARR']['DIV_DATE'] = array(
'#type' => 'textfield',
'#title' => t('Date of Separation'),
'#description'=>t('Year-Month-Day YYYY-MM-DD'),
'#default_value' => $node->DIV_DATE,
);
$form['MARR']['DIV_PLAC'] = array(
'#type' => 'textfield',
'#title' => t('Place of Separation'),
'#default_value' => $node->DIV_PLAC,
);
$parents=array();
$indivs=db_query('SELECT nid, title_format FROM {family_individual}');
while($data = mysql_fetch_array($indivs)){
$parents[$data['nid']]=$data['title_format'];
}
$form['PAR1'] = array(
'#type' => 'select',
'#title' => t('Parent 1'),
'#default_value' => $node->PAR1,
'#options'=> array('' => 'Unknown', 'Individuals'=>$parents),
'#description'=>t('The parent whose last name is carried by the children.'),
);
$form['PAR1'] = array(
'#type' => 'select',
'#title' => t('Parent 2'),
'#default_value' => $node->PAR2,
'#options'=> array('' => 'Unknown', 'Individuals'=>$parents),
);
$form['body_filter']['body'] = array(
'#type' => 'textarea',
'#title' => t('Biography'),
'#default_value' => $node->body,
'#rows' => 20,
'#required' => FALSE,
'#weight' => 2
);
$form['body_filter']['format'] = filter_form($node->format); //Not sure why this goes here, but all the examples have it...
return $form;
} // function family_group_form(&$node, &$param)
/**
* Implementation of hook_insert().
*/
function family_group_insert($node) {
$node->title = $node->'The Family of '.$node->PAR1.' & '.node->PAR2;
db_query("INSERT INTO {family_group} (vid, nid, title_format, marr_type, marr_date, marr_plac, div_date, div_plac, parent1, parent2) VALUES (%d, ,%d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s')",
$node->vid, $node->nid, $node->NAME, $node->MARR_TYPE, $node->MARR_DATE, $node->MARR_PLAC, $node->DIV_DATE,$node->DIV_PLAC, $node->PAR1, $node->PAR2);
} //function family_group_form()
/**
* Implementation of hook_load().
*/
function family_group_load($node) {
$additions = db_fetch_object(db_query('SELECT * FROM {family_group} WHERE nid = %d', $node->nid));
return $additions;
} //function family_group_load()
/**
* Implementation of hook_update().
*/
function family_group_update($node) {
$node->title = $node->'The Family of '.$node->PAR1.' & '.node->PAR2;
// if this is a new node or we're adding a new revision,
if ($node->revision) {
family_group_insert($node);
}
else {
db_query("UPDATE {family_group} SET title_format='%s', marr_type='%s', marr_date='%s', marr_plac='%s', div_date='%s', div_plac='%s', parent1='%s', parent2='%s' WHERE nid='%d'",
$node->NAME, $node->MARR_TYPE, $node->MARR_DATE, $node->MARR_PLAC, $node->DIV_DATE, $node->DIV_PLAC,$node->PAR1, $node->PAR2, $node->nid);
} //function family_group_update()
/**
* Implementation of hook_view().
*/
function family_group_view(&$node, $teaser = FALSE, $page = FALSE) {
$node = node_prepare($node, $teaser);
$node->content['family_group_view'] = array(
'#value' => theme($teaser? 'family_group_teaser':'family_group_body', $node),
'#weight' => -1,
);
return $node;
} //function family_group_view()
function theme_family_group_teaser($node) {
return family_view_group($node->nid,$type=0);
}
function theme_family_group_body($node) {
return family_view_group($node->nid,$type=1);
}
/**
* Implementation of hook_delete().
*/
function family_group_delete(&$node) {
db_query('DELETE FROM {family_group} WHERE nid = %d', $node->nid);
} //function family_group_delete
And now View.inc
function family_view_group($nid,$type) {$content="";
$content .= family_summ_group ($nid);
//Find children of the family group
$children = db_query("SELECT * FROM (family_individual) WHERE ancestor_group = %d", $nid);
if ($children) {
$child_list = array();
while ($child = mysql_fetch_array($children)) {
#43
:( my computers getting slow as this page is way too long!
did you get the e-mail's i sent you yesterday? i think i sent three. replying to your posts above and including the skype name and pics for tree. i also included a quick form for location and implemented your form for group (i also did what you've done above but looking at them i think yours will probably work better) i didn't do any of the view functions though. in your script above though you need to include a db_query in the update and insert hooks for saving the title (it doesn't do it otherwise)
db_query("UPDATE {node} SET title='%s' WHERE nid='%d'",$node->title,$node->nid);also the title_format needs to be created and saved in these hooks as it is need to display the list on the individuals form. i just did something like:
$parent1=mysql_fetch_array(db_query("SELECT firstname, lastname FROM {family_individual} WHERE nid='%d'",$node->PAR1));
$parent2=mysql_fetch_array(db_query("SELECT firstname FROM {family_individual} WHERE nid='%d'",$node->PAR2));
$node->title_format = ($parent1['firstname']).' and '.($parent2['firstname']).' '.($parent1['lastname']);
i tried an update script but it keeps running out of memory on the database i'm testing it on, which only has about 80 individuals, so i gave up. i will create the location view and you can do the group view if you want. i think location values (e.g. birthplace) should have an to check if they are a number and if so use it as an nid tag and create a link with the correct address. i will give this a go and send you any results.
#44
for saving the title also add
db_query("UPDATE {node_revisions} SET title='%s' WHERE nid='%d' AND vid='%d'",$node->title, $node->nid, $node->vid);i found otherwise it doesn't actually show the title on the page itself
#45
Guys,
I went on your site, and I think the work you have done is fantastic.
I am new to Drupal, but plan to add your family module. I have questions about how I was going to implement your family module:
1) I wanted to create a family for one particular user. So the user will be entering in info for his family, and the fields of the members I am mostly interested in are name, sex, year of birth. Is that possible to change the admin config for Family to only require these values to be entered by a user?
2) Is there a way to create a module that lets the user select a proxy for his family member (say a user acting for his 50 year old mother by selecting her in a drop down menu)? Or would this be easier done by hard coding the html page (although I prefer to stay within the Drupal model itself, hence a module). You will see why in #3 & 4. And where would you save this proxy information, in a php session variable, cookie, sql db?
3) when posting images and forum posts and blogs, is there a way to tag (via token, taxonomy, or active select) these media elements with the proxy's info. So if the user enters a blog, it would be tagged with "female" and "50"?
4) acting as the proxy (eg, again for the 50 yo woman), can the user search and retrieve forum, blogs, groups, etc, with a filter for the proxy's info (age and sex)? So the user will be shown only events or topics which are age-appropriate for the proxy (eg, events which other users have tagged as for those who are 45-55 and female)? And then the user could switch back to himself (or another family member) and the data from forum and blogs would switch accordingly?
Thanks for your help,
George
#46
subscribe
#47
George,
some attempted replies to your questions.
this is on our list of developments to make but it is quite hard to achieve. however it would be simple to add a permission for editting the pages they have created like for the node module if this is what you want.
No fields are 'required' fields as family individuals you might only know there name or there dob.
these arn't particualaly good answers as what i think you are trying to achieve requires a combination of other modules as well.
if any of the suggestions i have made sounds like they could be the answer post back and i will see if i can implement them into the module.
Microbe
#48
Reviewing this page and seeing all work you guys have done is great. I didnt see this when I posted my request for assistance. I realize now that you have not worked on the import function. Do you have any idea when that will be done? That part is pivotal to my recreating my site. I had previously used PDF reports so that I could share information with my family but I dont want to have to retype everything. So I can import GEDCOM data, that would be great. Thanks again for all the effort you have put into this. I can tell you it is very much appreciated.
Marcia
#49
Sorry I forgot to add that if you cant import GEDCOM files maybe there is a way to use the node import module to bring the information. I tried to do that but could not map the fields.
Marcia
#50
I don't believe the node import will be possible. I'm checking with microbe to see if import is enabled yet. If not, it will be our next step.
#51
node import uses CSV but GEDCOM has its own, more complicated, structure. import still currently doesn't work :( i will have a look at it over the next week if pyutaros thinks that is the best thing i can do to help. :)
#52
Since the redesign is completed, I am closing this issue and will open a new one to document progress on import for 5.x-3.x, which has already started.
#53
oops
#54
Automatically closed -- issue fixed for two weeks with no activity.