{"id":13625690,"url":"https://github.com/straup/privatesquare","last_synced_at":"2025-04-06T01:33:10.662Z","repository":{"id":2290434,"uuid":"3248330","full_name":"straup/privatesquare","owner":"straup","description":"privatesquare is a simple web application to record and manage a database of foursquare check-ins.","archived":false,"fork":false,"pushed_at":"2023-12-21T03:02:43.000Z","size":10080,"stargazers_count":59,"open_issues_count":3,"forks_count":15,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-03-21T15:42:37.197Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"http://straup.github.com/privatesquare/","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-2-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/straup.png","metadata":{"files":{"readme":"README.FLAMEWORK.md","changelog":"CHANGES.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2012-01-23T16:46:43.000Z","updated_at":"2023-12-21T02:51:36.000Z","dependencies_parsed_at":"2024-01-14T07:19:41.213Z","dependency_job_id":null,"html_url":"https://github.com/straup/privatesquare","commit_stats":null,"previous_names":[],"tags_count":19,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/straup%2Fprivatesquare","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/straup%2Fprivatesquare/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/straup%2Fprivatesquare/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/straup%2Fprivatesquare/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/straup","download_url":"https://codeload.github.com/straup/privatesquare/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247423497,"owners_count":20936622,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-01T21:01:59.670Z","updated_at":"2025-04-06T01:33:05.646Z","avatar_url":"https://github.com/straup.png","language":"PHP","funding_links":[],"categories":["PHP"],"sub_categories":[],"readme":"Flamework\n=========\n\nFlamework is the semi-fictional framework that powers Flickr.com. It's\nless of an actual framework and more of a design philosophy. None of\nthe code in this project is actually taken from Flickr, but is rather\na reconstruction of the way we built things there and the way we\ncontinue to build things now.\n\n\u003cb\u003eThis library is a work in progress\u003c/b\u003e. While it basically works,\nit's lacking lots of the bits it really needs. As we pull these parts\nfrom other projects (and I've built most parts 10 times over by now),\nit'll start to take better shape. If you have stuff you want to add,\nfork, commit and file a pull-request.\n\n## Installation - As a base for a new project\n\n* Copy everything in \u003ccode\u003ewww\u003c/code\u003e to a web server running Apache with \u003ccode\u003emod_php\u003c/code\u003e and \u003ccode\u003ephp5-mcrypt\u003c/code\u003e.\n* Enable \u003ccode\u003eAllowOverrides all\u003c/code\u003e for the root.\n* Copy \u003ccode\u003einclude/config.php.example\u003c/code\u003e to \u003ccode\u003einclude/config.php\u003c/code\u003e and edit it.\n* Ensure that the \u003ccode\u003etemplates_c\u003c/code\u003e directory can be written to by your webserver.\n* Load the schema into mysql: \u003ccode\u003emysql -uwww -Dflamework -p \u003c schema/db_main.schema\u003c/code\u003e\n\nThat might be it.\n\nIf you'd like to use Flamework as an external library, \u003ca href=\"/exflickr/flamework/blob/master/docs/install_external.md\"\u003eread this\u003c/a\u003e.\n\n## Statement(s) of Bias\n\n*\"Working on the crumbly edge of future-proofing.\" -- [Heather Champ](http://www.hchamp.com/)*\n\nIf you've never watched [Cal Henderson's](http://www.iamcal.com) \"Why I Hate Django\" presentation now is probably as good a time as any. It will help you understand a lot about why things were done they were at Flickr and why those of us who've left prefer to keep doing them that way:\n\n+ [http://www.youtube.com/watch?v=i6Fr65PFqfk](http://www.youtube.com/watch?v=i6Fr65PFqfk \"Why I Hate Django\")\n\nFlamework is not really a framework, at least not by most people's standards. All software development is basically pain management and Flamework assumes that the most important thing is *the speed with which the code running an application can be re-arranged, in order to adapt to circumstances*, even if it's at the cost of \"doing things twice\" or \"repeating ourselves\".\n\n**Flamework is basically two things:**\n\n1. A set of common libraries and functions.\n2. A series of social conventions for how code is arranged.\n\n**Flamework also takes the following for granted:**\n\n* It uses [Smarty](http://www.smarty.net \"Smarty\") for templating.\n* It uses global variables. Not many of them but it also doesn't make a fuss about the idea of using them.\n* It does not use objects or \"protected\" variables.\n* It breaks it own rules occasionally and uses objects but only rarely and generally when they are defined by third-party libraries (like [Smarty](http://www.smarty.net/)).\n* That [\"normalized data is for sissies\"](http://kottke.org/04/10/normalized-data).\n\n**For all intents and purposes, Flamework *is* a model-view-controller (MVC) system:**\n\n* There are shared libraries (the model)\n* There are PHP files (the controller)\n* There are templates (the view)\n\nHere is a simple bare-bones example of how it all fits together:\n\n\t# lib_example.php\n\n\t\u003c?php\n\t\tfunction example_foo(\u0026$user){\n\t\t\t$max = ($user['id']) ? $user['id'] : 1000;\n\t\t\treturn range(0, rand(0, $max));\n\t\t}\n\t?\u003e\n\n\t# example.php\n\t#\n\t# note how we're importing lib_example.php (above)\n\t# and squirting everything out to page_example.txt (below)\n\n\t\u003c?php\u003e\n\t\tinclude(\"include/init.php\");\n\t\tloadlib(\"example\");\n\n\t\t$foo = example_foo($GLOBALS['cfg']['user']);\n\n\t\t$GLOBALS['smarty']-\u003eassign_by_ref(\"foo\", $foo);\n\t\t$GLOBALS['smarty']-\u003edisplay(\"page_example.txt\");\n\t\texit();\n\t?\u003e\n\n\t# page_example.txt\n\n\t{assign var=\"page_title\" value=\"example page title\"}\n\t{include file=\"inc_head.txt\"}\n\t\u003cp\u003e{if $cfg.user.id}Hello, {$cfg.user.username|escape}!{else}Hello, stranger!{/if}\u003c/p\u003e\n\t\u003cp\u003efoo is: {$foo|@join(\",\")|escape}\u003c/p\u003e\n\t{include file=\"inc_foot.txt\"}\n\nThe only \"rules\" here are:\n\n1. Making sure you load `include/init.php`\n2. The part where `init.php` handles authentication checking and assigns logged in users to the global `$cfg` variable (it also creates and assigns a global `$smarty` object)\n3. The naming conventions for shared libraries, specifically: `lib_SOMETHING.php` which is imported as `loadlib(\"SOMETHING\")`.\n4. Functions defined in libraries are essentially \"namespaced\".\n\nPage template names and all that other stuff is, ultimately, your business.\n\nGlobal Variables\n--\n\nFlamework uses and assigns global PHP variables on the grounds that it's really just not that big a deal. A non-exhaustive list of global variables that Flameworks assigns is:\n\n* $GLOBALS['cfg'] -- this is a great big hash that contains all the various site configs\n\n* $GLOBALS['smarty'] -- a [Smarty](http://www.smarty.net/) templating object\n\n* $GLOBALS['timings'] -- a hash used to store site performance metrics\n\n* $GLOBALS['loaded_libs'] -- a hash used to store information about libraries that have been loaded\n\n* $GLOBALS['local_cache'] -- a hash used to store locally cached data\n\n* $GLOBALS['error'] -- a (helper) hash used to assign site errors to; this is also automagically assigned to a corresponding Smarty variable\n\nThe database model\n--\n\nFlamework assumes a federated model with all the various user data spread across a series of databases, or \"clusters\". For each cluster there are a series of corresponding helper functions defined in `lib_db.php`.\n\n**By default Flamework does not require that it be run under a fully-federated\n  database system.** It takes advantage of the ability to run in \"poor man's\n  federated\" mode which causes the database libraries to act as though there are\n  multiple database clusters when there's only really one. Specifically, all the\n  various databases are treated as though they live in the `db_main`\n  cluster. The goal is to enable (and ensure) that when a given installation of\n  a Flamework project outgrows a simple one or two machine setup that it can easily be migrated to a more robust system with a minimum of fuss.\n\nAs of this writing Flamework defines/expects the following clusters:\n\n+ **db_main**\n\nThis is the database cluster where user accounts and other lookup-style database tables live.\n\n+ **db_users**\n\nThese are the federated tables, sometimes called \"shards\". This is where the bulk of the data in Dotspotting is stored because it can be spread out, in smaller chunks, across a whole bunch of databases rather than a single monolithic monster database that becomes a single point of failure and it just generally a nuisance to maintain.\n\n+ **db_tickets**\n\nOne of the things about storing federated user data is that from time to time you may need to \"re-balance\" your shards, for example moving all of a user's data from shard #5 to shard #23. That means you can no longer rely on an individual database to generate auto-incrementing unique IDs because each database shard creates those IDs in isolation and if you try to move a dot, for example, with ID `123` to a shard with another dot that already has the same ID everything will break and there will be tears.\n\nThe way around this is to use \"ticketing\" servers whose only job is to sit around and assign unique IDs. A discussion of ticketing servers is outside the scope of this document but [Kellan wrote a good blog post about the subject](http://code.flickr.com/blog/2010/02/08/ticket-servers-distributed-unique-primary-keys-on-the-cheap/) if you're interested in learning more. Which is a long way of saying: Flamework uses tickets and they come from the `db_tickets` cluster.\n\t   \n## Other documentation\n\n* \u003ca href=\"/exflickr/flamework/blob/master/docs/troubleshooting.md\"\u003eTroubleshooting\u003c/a\u003e\n* \u003ca href=\"/exflickr/flamework/blob/master/docs/style_guide.md\"\u003eStyle guide\u003c/a\u003e\n\n\n## Libraries \u0026 Tools\n\nThere are several drop-in external libraries for common tasks:\n\n* \u003ca href=\"https://github.com/straup/flamework-geo\"\u003eflamework-geo\u003c/a\u003e - Geo libraries and helper functions\n* \u003ca href=\"https://github.com/straup/flamework-aws\"\u003eflamework-aws\u003c/a\u003e - S3 upload library\n* \u003ca href=\"https://github.com/straup/flamework-api\"\u003eflamework-api\u003c/a\u003e - Add an external API\n* \u003ca href=\"https://github.com/straup/flamework-invitecodes\"\u003eflamework-invitecodes\u003c/a\u003e - Generate invite codes\n* \u003ca href=\"https://github.com/iamcal/flamework-useragent\"\u003eflamework-useragent\u003c/a\u003e - Parse useragent strings\n* \u003ca href=\"https://github.com/iamcal/flamework-JSON\"\u003eflamework-JSON\u003c/a\u003e - Parse invalid JSON\n\n\u003ca href=\"https://github.com/straup/\"\u003eAaron\u003c/a\u003e has created several starter configurations for using delegated auth:\n\n* \u003ca href=\"https://github.com/straup/flamework-flickrapp\"\u003eflamework-flickrapp\u003c/a\u003e - Authenticate using Flickr\n* \u003ca href=\"https://github.com/straup/flamework-twitterapp\"\u003eflamework-twitterapp\u003c/a\u003e -  Authenticate using Twitter\n* \u003ca href=\"https://github.com/straup/flamework-foursquareapp\"\u003eflamework-foursquareapp\u003c/a\u003e - Authenticate using foursquare\n* \u003ca href=\"https://github.com/straup/flamework-osmapp\"\u003eflamework-osmapp\u003c/a\u003e - Authenticate using OpenStreetMap\n\nAnd some random odds and ends:\n\n* \u003ca href=\"https://github.com/straup/flamework\"\u003eflamework-tools\u003c/a\u003e - Automation scripts\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstraup%2Fprivatesquare","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fstraup%2Fprivatesquare","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstraup%2Fprivatesquare/lists"}