Compare commits
	
		
			274 Commits
		
	
	
		
			master
			...
			feature.we
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					cdb8dbafe2 | ||
| 
						 | 
					33b22f95ab | ||
| 
						 | 
					39f77886db | ||
| 
						 | 
					f7470e4a7a | ||
| 
						 | 
					c10c002ee3 | ||
| 
						 | 
					a47ec0df0a | ||
| 
						 | 
					be95050a4b | ||
| 
						 | 
					5043c4e845 | ||
| 
						 | 
					dacbf0707b | ||
| 
						 | 
					34c9d04a35 | ||
| 
						 | 
					aa2868eb17 | ||
| 
						 | 
					a2c832a130 | ||
| 
						 | 
					b17de014ec | ||
| 
						 | 
					b1b72190e1 | ||
| 
						 | 
					2ff2f888bc | ||
| 
						 | 
					57c2389aae | ||
| 
						 | 
					d54c86f813 | ||
| 
						 | 
					05a9697007 | ||
| 
						 | 
					945429abf0 | ||
| 
						 | 
					a016bcb51b | ||
| 
						 | 
					f2b1ce795c | ||
| 
						 | 
					3a8c56acc4 | ||
| 
						 | 
					7b2552f940 | ||
| 
						 | 
					324b202215 | ||
| 
						 | 
					2c2da6082a | ||
| 
						 | 
					dd3fbbd7e4 | ||
| 
						 | 
					9bbcd571ec | ||
| 
						 | 
					bbc185bf3b | ||
| 
						 | 
					d1bcdcda20 | ||
| 
						 | 
					6d55602ef3 | ||
| 
						 | 
					6e7c9f7c4b | ||
| 
						 | 
					5427aab456 | ||
| 
						 | 
					4879d64989 | ||
| 
						 | 
					dab8ea63fc | ||
| 
						 | 
					b03d7a04a0 | ||
| 
						 | 
					ef5b93e3f7 | ||
| 
						 | 
					69ae1c08ef | ||
| 
						 | 
					8e4f828cc6 | ||
| 
						 | 
					c4f92f4569 | ||
| 
						 | 
					c4d2b99656 | ||
| 
						 | 
					d4fe88adab | ||
| 
						 | 
					69d0e8313a | ||
| 
						 | 
					11a234e135 | ||
| 
						 | 
					2f30e4e2f6 | ||
| 
						 | 
					118ca9f11f | ||
| 
						 | 
					24fc41ee0d | ||
| 
						 | 
					c00dbac5e0 | ||
| 
						 | 
					d7857c5126 | ||
| 
						 | 
					ac6be0d3c0 | ||
| 
						 | 
					7ff6f09f67 | ||
| 
						 | 
					00b576c5a3 | ||
| 
						 | 
					2a33510c96 | ||
| 
						 | 
					d1f79d906d | ||
| 
						 | 
					aa043f14ac | ||
| 
						 | 
					638b28399e | ||
| 
						 | 
					1d86f036a3 | ||
| 
						 | 
					2f6e0f0a22 | ||
| 
						 | 
					1b1b00a10c | ||
| 
						 | 
					8693418d39 | ||
| 
						 | 
					8ff15368ce | ||
| 
						 | 
					32cde534bd | ||
| 
						 | 
					c0e26133bd | ||
| 
						 | 
					592c2ff9ff | ||
| 
						 | 
					30efd0a2db | ||
| 
						 | 
					20c3f14cc8 | ||
| 
						 | 
					80313c88c8 | ||
| 
						 | 
					cab1c09ffc | ||
| 
						 | 
					c421919092 | ||
| 
						 | 
					d350876bc1 | ||
| 
						 | 
					de09c8af56 | ||
| 
						 | 
					998f4576fe | ||
| 
						 | 
					06c57f7da6 | ||
| 
						 | 
					4d5418a601 | ||
| 
						 | 
					95cc7f627f | ||
| 
						 | 
					2aab4eea3b | ||
| 
						 | 
					5bbff9f5a6 | ||
| 
						 | 
					b5fcf1636a | ||
| 
						 | 
					13012be5d7 | ||
| 
						 | 
					ca2ef814fb | ||
| 
						 | 
					b9407f6aee | ||
| 
						 | 
					9bcb5f9456 | ||
| 
						 | 
					f412099f69 | ||
| 
						 | 
					0aa5999bb3 | ||
| 
						 | 
					16dda0743c | ||
| 
						 | 
					d079838818 | ||
| 
						 | 
					81ce4688df | ||
| 
						 | 
					ee33cc1832 | ||
| 
						 | 
					82bb18fe10 | ||
| 
						 | 
					8987ca7db6 | ||
| 
						 | 
					8066fd8982 | ||
| 
						 | 
					a96d8c05a7 | ||
| 
						 | 
					4238a5dd50 | ||
| 
						 | 
					94da55d15e | ||
| 
						 | 
					09979b8551 | ||
| 
						 | 
					5b82efa0be | ||
| 
						 | 
					8502a36481 | ||
| 
						 | 
					bcba64b2a1 | ||
| 
						 | 
					e40d922eef | ||
| 
						 | 
					7e226b43d3 | ||
| 
						 | 
					9171bfd1ab | ||
| 
						 | 
					be4774c95c | ||
| 
						 | 
					bbf1a1882a | ||
| 
						 | 
					9644784a79 | ||
| 
						 | 
					1940d5c0b5 | ||
| 
						 | 
					7c7e3cd1f1 | ||
| 
						 | 
					3e2f95a152 | ||
| 
						 | 
					92de88ba13 | ||
| 
						 | 
					5322cdf609 | ||
| 
						 | 
					02d0f0923e | ||
| 
						 | 
					765a86ba90 | ||
| 
						 | 
					34309e34c3 | ||
| 
						 | 
					2176d1cde2 | ||
| 
						 | 
					45d53e8d21 | ||
| 
						 | 
					b36b8e3afb | ||
| 
						 | 
					801af66a4e | ||
| 
						 | 
					df6ffdf420 | ||
| 
						 | 
					b3368071ac | ||
| 
						 | 
					67b80ee11c | ||
| 
						 | 
					dc31155de1 | ||
| 
						 | 
					0bae69908b | ||
| 
						 | 
					47a077bc82 | ||
| 
						 | 
					836ff71364 | ||
| 
						 | 
					0afa07b2bd | ||
| 
						 | 
					4ee3d471fe | ||
| 
						 | 
					29c7fed81b | ||
| 
						 | 
					fb62061e5a | ||
| 
						 | 
					9b92b7139f | ||
| 
						 | 
					5ea4b02205 | ||
| 
						 | 
					12d3eef3d1 | ||
| 
						 | 
					576c06ffaf | ||
| 
						 | 
					352dc3e179 | ||
| 
						 | 
					aa164936f4 | ||
| 
						 | 
					9a93acd1a5 | ||
| 
						 | 
					587aa11cda | ||
| 
						 | 
					d04ecd60c4 | ||
| 
						 | 
					ecef510f78 | ||
| 
						 | 
					4976c20935 | ||
| 
						 | 
					5553c37ccd | ||
| 
						 | 
					346b2c6cf8 | ||
| 
						 | 
					aa68fe3485 | ||
| 
						 | 
					e408fe8733 | ||
| 
						 | 
					836986462a | ||
| 
						 | 
					51c6cdb20d | ||
| 
						 | 
					766232f29b | ||
| 
						 | 
					2ed021f30b | ||
| 
						 | 
					899fe561df | ||
| 
						 | 
					67d8936083 | ||
| 
						 | 
					78f5cef5bd | ||
| 
						 | 
					8928b1654c | ||
| 
						 | 
					977fa0d1d4 | ||
| 
						 | 
					1d89cec2cf | ||
| 
						 | 
					6c6b7d6bb2 | ||
| 
						 | 
					f92e88e9b4 | ||
| 
						 | 
					6e58899fdf | ||
| 
						 | 
					1513598420 | ||
| 
						 | 
					9cfc060760 | ||
| 
						 | 
					a531e34ec2 | ||
| 
						 | 
					2cce23b5b4 | ||
| 
						 | 
					e518bc9b68 | ||
| 
						 | 
					8e02d05ba9 | ||
| 
						 | 
					f131083315 | ||
| 
						 | 
					39ba5b37ef | ||
| 
						 | 
					002fa05c7f | ||
| 
						 | 
					1a52133fd4 | ||
| 
						 | 
					30900f7196 | ||
| 
						 | 
					b753cf0837 | ||
| 
						 | 
					53ab5b6aff | ||
| 
						 | 
					78a0402351 | ||
| 
						 | 
					5b5705fe90 | ||
| 
						 | 
					f08b5c5e3f | ||
| 
						 | 
					aa87acd432 | ||
| 
						 | 
					7af7ef8357 | ||
| 
						 | 
					627bc4e45f | ||
| 
						 | 
					909c76ebfb | ||
| 
						 | 
					0899ba8515 | ||
| 
						 | 
					b7c0b40491 | ||
| 
						 | 
					48257ccfed | ||
| 
						 | 
					269949a65f | ||
| 
						 | 
					c2de7123e4 | ||
| 
						 | 
					e0c6dcd5a4 | ||
| 
						 | 
					734ddda363 | ||
| 
						 | 
					02cd448f89 | ||
| 
						 | 
					5fc3a987de | ||
| 
						 | 
					be39d72d3c | ||
| 
						 | 
					045eb766f1 | ||
| 
						 | 
					22d4bd0e6f | ||
| 
						 | 
					5a7bf49cbb | ||
| 
						 | 
					a3dd1c45f3 | ||
| 
						 | 
					be7725694e | ||
| 
						 | 
					366d278182 | ||
| 
						 | 
					5f008a14f5 | ||
| 
						 | 
					21a8c281ec | ||
| 
						 | 
					51dde5766d | ||
| 
						 | 
					61d7b4a58d | ||
| 
						 | 
					19b35565a2 | ||
| 
						 | 
					baa88412b9 | ||
| 
						 | 
					6fb9b72e22 | ||
| 
						 | 
					b75884c57e | ||
| 
						 | 
					603188f6ce | ||
| 
						 | 
					15442140cf | ||
| 
						 | 
					9f877d4309 | ||
| 
						 | 
					8631529268 | ||
| 
						 | 
					96bc198b0f | ||
| 
						 | 
					146ffb5f4c | ||
| 
						 | 
					867c3d3382 | ||
| 
						 | 
					75b0f27fe2 | ||
| 
						 | 
					4b001d8f03 | ||
| 
						 | 
					a7bec96a80 | ||
| 
						 | 
					a8706e38ca | ||
| 
						 | 
					265fd41717 | ||
| 
						 | 
					67c23ffe24 | ||
| 
						 | 
					e9a09889e4 | ||
| 
						 | 
					e6756a2072 | ||
| 
						 | 
					f4050b8a76 | ||
| 
						 | 
					bb4fa7ca2f | ||
| 
						 | 
					2648603f24 | ||
| 
						 | 
					b7a9a1c8fd | ||
| 
						 | 
					d45566d692 | ||
| 
						 | 
					4411086f29 | ||
| 
						 | 
					0b3ce03036 | ||
| 
						 | 
					027886737d | ||
| 
						 | 
					35f45015ea | ||
| 
						 | 
					618f412bed | ||
| 
						 | 
					6ab9c754a5 | ||
| 
						 | 
					c59332c8f8 | ||
| 
						 | 
					32d9d04b4b | ||
| 
						 | 
					62d0fb6eee | ||
| 
						 | 
					bc82ee24d8 | ||
| 
						 | 
					6ab1f4a4f0 | ||
| 
						 | 
					3e6527bab3 | ||
| 
						 | 
					9b7691c1ae | ||
| 
						 | 
					c3cd494386 | ||
| 
						 | 
					fba5841bdc | ||
| 
						 | 
					da7fc3e7e3 | ||
| 
						 | 
					00ebe1633c | ||
| 
						 | 
					f63bfcb4f6 | ||
| 
						 | 
					177cf836b4 | ||
| 
						 | 
					04069871bb | ||
| 
						 | 
					31469204e0 | ||
| 
						 | 
					9b148c8c4a | ||
| 
						 | 
					98f4eac82a | ||
| 
						 | 
					29d966cdb3 | ||
| 
						 | 
					23d2bd552c | ||
| 
						 | 
					41cfbbd0d9 | ||
| 
						 | 
					cc89a7e6f8 | ||
| 
						 | 
					c486fe98fb | ||
| 
						 | 
					f0ac256ff6 | ||
| 
						 | 
					e4b3adb2f5 | ||
| 
						 | 
					58a5bc46d9 | ||
| 
						 | 
					6e5c3a551d | ||
| 
						 | 
					52f8261d8c | ||
| 
						 | 
					721c385993 | ||
| 
						 | 
					9c80de19d7 | ||
| 
						 | 
					4ffd11caf5 | ||
| 
						 | 
					f2c4faf054 | ||
| 
						 | 
					bc54b663e0 | ||
| 
						 | 
					6f1bb309d4 | ||
| 
						 | 
					cdedaa4604 | ||
| 
						 | 
					2130b327df | ||
| 
						 | 
					3e238bea0b | ||
| 
						 | 
					266c297632 | ||
| 
						 | 
					4477b07bc6 | ||
| 
						 | 
					74b44186d2 | ||
| 
						 | 
					c2bf1bac38 | ||
| 
						 | 
					c279313048 | ||
| 
						 | 
					0301ba0336 | ||
| 
						 | 
					5e6d61b3a7 | ||
| 
						 | 
					4e00051a10 | ||
| 
						 | 
					38e6e4f8d3 | ||
| 
						 | 
					dfa223b39e | ||
| 
						 | 
					0a8d771c11 | ||
| 
						 | 
					5afd073ff3 | ||
| 
						 | 
					46fda14e08 | ||
| 
						 | 
					bbf9ef8b3d | 
							
								
								
									
										1
									
								
								.gitattributes
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								.gitattributes
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1 @@
 | 
				
			|||||||
 | 
					src/IDF/version.php     export-subst
 | 
				
			||||||
							
								
								
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							@@ -9,3 +9,6 @@ indefero-*.zip
 | 
				
			|||||||
src/IDF/conf/path.php
 | 
					src/IDF/conf/path.php
 | 
				
			||||||
.tx/config
 | 
					.tx/config
 | 
				
			||||||
src/IDF/locale/idf.pot.bak
 | 
					src/IDF/locale/idf.pot.bak
 | 
				
			||||||
 | 
					test/test.db
 | 
				
			||||||
 | 
					test/tmp
 | 
				
			||||||
 | 
					test/config.php
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										55
									
								
								AUTHORS
									
									
									
									
									
								
							
							
						
						
									
										55
									
								
								AUTHORS
									
									
									
									
									
								
							@@ -1,30 +1,43 @@
 | 
				
			|||||||
InDefero was originally created during summer 2008 
 | 
					InDefero was originally created during summer 2008
 | 
				
			||||||
by Loïc d'Anterroches with the support of Céondo Ltd.
 | 
					by Loïc d'Anterroches with the support of Céondo Ltd.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Much appreciated contributors:
 | 
					Much appreciated contributors (in alphabetical order):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Nicolas Lassalle <http://www.beroot.org/> - Subversion support
 | 
					    Adrien Bustany <madcat@mymadcat.com>
 | 
				
			||||||
    bohwaz <http://bohwaz.net/>
 | 
					    Andrew Nguyen <andrew-git-indefero@na-consulting.net>
 | 
				
			||||||
    Benjamin Jorand <benjamin.jorand@gmail.com> - Mercurial support
 | 
					    Baptiste Durand-Bret <bathizte@ozazar.org>
 | 
				
			||||||
    Baptiste Michaud <bactisme@gmail.com> - Subversion synchronization
 | 
					    Baptiste Michaud <bactisme@gmail.com>           - Subversion sync
 | 
				
			||||||
    Julien Issler 
 | 
					    Benjamin Jorand <benjamin.jorand@gmail.com>     - Mercurial support
 | 
				
			||||||
 | 
					    Brenda Wallace <shiny@cpan.org>
 | 
				
			||||||
 | 
					    Brian Armstrong <brianar>
 | 
				
			||||||
 | 
					    Charles Melbye <charlie@yourwiki.net>
 | 
				
			||||||
 | 
					    Ciaran Gultnieks <ciaran@ciarang.com>
 | 
				
			||||||
 | 
					    Daniel Steudler <steudlerdaniel@gmail.com>
 | 
				
			||||||
 | 
					    David Feeney <davidf>
 | 
				
			||||||
 | 
					    Denis Kot <denis.kot@gmail.com>                 - Russian translation
 | 
				
			||||||
 | 
					    Dmitry Dulepov <dmitryd>
 | 
				
			||||||
 | 
					    Fernando Sayago Gil <mikados.mikados@gmail.com> - Spanish translation
 | 
				
			||||||
 | 
					    Jakub Viták <mainiak@gmail.com>                 - Czech translation
 | 
				
			||||||
 | 
					    Janez Troha <http://www.dz0ny.info>             - Slovenian translation
 | 
				
			||||||
 | 
					    Jean-Philippe Fleury <jpfleury>
 | 
				
			||||||
 | 
					    Jerry <lxb429@gmail.com>                        - Chinese translation
 | 
				
			||||||
 | 
					    Julien Issler <julien@issler.net>
 | 
				
			||||||
 | 
					    Ludovic Bellière <xrogaan>
 | 
				
			||||||
    Manuel Eidenberger <eidenberger@gmail.com>
 | 
					    Manuel Eidenberger <eidenberger@gmail.com>
 | 
				
			||||||
    Ciaran Gultnieks
 | 
					    Matthew Dawson <mjd>
 | 
				
			||||||
 | 
					    Matías Halles <matias@halles.cl>
 | 
				
			||||||
    Mehdi Kabab <http://pioupioum.fr/>
 | 
					    Mehdi Kabab <http://pioupioum.fr/>
 | 
				
			||||||
    Sindre R. Myren
 | 
					    Nicolas Lassalle <nicolas@beroot.org>           - Subversion support
 | 
				
			||||||
    Patrick Georgi <patrick.georgi@coresystems.de>
 | 
					    Patrick Georgi <patrick.georgi@coresystems.de>
 | 
				
			||||||
    Adrien Bustany
 | 
					    Raphaël Emourgeon <raphael>
 | 
				
			||||||
    Charles Melbye
 | 
					    Samuel Suther <info@suther.de>                  - German translation
 | 
				
			||||||
    Baptiste Durand-Bret
 | 
					    Sindre R. Myren <sindrero@stud.ntnu.no>
 | 
				
			||||||
    Andrew Nguyen
 | 
					    Stewart Platt <stew@futurete.ch>
 | 
				
			||||||
    David Feeney
 | 
					    Thomas Keller <me@thomaskeller.biz>             - Monotone support
 | 
				
			||||||
    Denis Kot <denis.kot@gmail.com>
 | 
					    Vladimir Solomatin <slash>
 | 
				
			||||||
    Samuel Suther
 | 
					    William Martin <william.martin@lcpc.fr>
 | 
				
			||||||
    Ludovic Bellière
 | 
					    Xavier Brochard <xavier@alternatif.org>
 | 
				
			||||||
    Brian Armstrong
 | 
					    bohwaz <http://bohwaz.net/>
 | 
				
			||||||
    Raphaël Emourgeon
 | 
					 | 
				
			||||||
    Jakub Viták
 | 
					 | 
				
			||||||
    Vladimir Solomatin
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
And all the nice users who spent time reporting issues and promoting
 | 
					And all the nice users who spent time reporting issues and promoting
 | 
				
			||||||
the project. The project could not live without them.
 | 
					the project. The project could not live without them.
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -104,12 +104,13 @@ without first talking to us.
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
## I am a translator
 | 
					## I am a translator
 | 
				
			||||||
 | 
					
 | 
				
			||||||
We currently use (transifex)[http://trac.transifex.org] to help our
 | 
					We currently use [transifex](http://trac.transifex.org) to help our
 | 
				
			||||||
users to translate indefero. You don't have to use it, but it's an
 | 
					users translate indefero. You don't have to use it, but it's an easy
 | 
				
			||||||
easy way to do the job. You can visit the indefero page at transifex
 | 
					way to do the job. You can visit the indefero page at transifex here:
 | 
				
			||||||
here : http://www.transifex.net/projects/p/indefero/c/indefero/
 | 
					
 | 
				
			||||||
 | 
					    http://www.transifex.net/projects/p/indefero/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Please understand that your changes will not be commited instantly,
 | 
					Please understand that your changes will not be commited instantly,
 | 
				
			||||||
but are sent to the maintainers e-mails before. Then, your changes
 | 
					but are sent to the maintainers e-mails before. Then, your changes
 | 
				
			||||||
will not be in the main repository until da-loic push the changes. In
 | 
					will not be in the main repository until the maintainer pushs the
 | 
				
			||||||
that way, try to do big changes with less submissions.
 | 
					changes. In that way, try to do big changes with less submissions.
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,6 +4,12 @@ The installation of InDefero is composed of 2 parts, first the
 | 
				
			|||||||
installation of the [Pluf framework](http://www.pluf.org) and second,
 | 
					installation of the [Pluf framework](http://www.pluf.org) and second,
 | 
				
			||||||
the installation of InDefero by itself.
 | 
					the installation of InDefero by itself.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## PHP modules for indefero
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Indefero need the GD module for PHP. It's named "php5-gd" in debian.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $ apt-get install php5-gd
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## Recommended Layout of the Files
 | 
					## Recommended Layout of the Files
 | 
				
			||||||
 | 
					
 | 
				
			||||||
If your server document root is in `/var/www` a good thing is to keep
 | 
					If your server document root is in `/var/www` a good thing is to keep
 | 
				
			||||||
@@ -37,6 +43,7 @@ docroot.
 | 
				
			|||||||
    $ sudo pear upgrade-all
 | 
					    $ sudo pear upgrade-all
 | 
				
			||||||
    $ sudo pear install --alldeps Mail
 | 
					    $ sudo pear install --alldeps Mail
 | 
				
			||||||
    $ sudo pear install --alldeps Mail_mime
 | 
					    $ sudo pear install --alldeps Mail_mime
 | 
				
			||||||
 | 
					    $ sudo pear install --alldeps Console_Getopt
 | 
				
			||||||
 | 
					
 | 
				
			||||||
If you already have some of the PEAR packages installed with your
 | 
					If you already have some of the PEAR packages installed with your
 | 
				
			||||||
distribution, the `Mail` package is often not up-to-date, 
 | 
					distribution, the `Mail` package is often not up-to-date, 
 | 
				
			||||||
@@ -125,6 +132,7 @@ The documentation is available in the `doc` folder.
 | 
				
			|||||||
* Subversion: `doc/syncsvn.mdtext`.
 | 
					* Subversion: `doc/syncsvn.mdtext`.
 | 
				
			||||||
* Mercurial: `doc/syncmercurial.mdtext`.
 | 
					* Mercurial: `doc/syncmercurial.mdtext`.
 | 
				
			||||||
* Git: `doc/syncgit.mdtext`.
 | 
					* Git: `doc/syncgit.mdtext`.
 | 
				
			||||||
 | 
					* Monotone: `doc/syncmonotone.mdtext`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## For the Apache Webserver Users
 | 
					## For the Apache Webserver Users
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -222,4 +230,4 @@ functions. You need to prevent the overload as it does not make sense
 | 
				
			|||||||
anyway (magic in the background is bad!). 
 | 
					anyway (magic in the background is bad!). 
 | 
				
			||||||
See the [corresponding ticket][reglink].
 | 
					See the [corresponding ticket][reglink].
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[reglink]: http://projects.ceondo.com/p/indefero/issues/481/
 | 
					[reglink]: http://projects.ceondo.com/p/indefero/issues/481/
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										114
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										114
									
								
								Makefile
									
									
									
									
									
								
							@@ -22,25 +22,40 @@
 | 
				
			|||||||
#   sudo apt-get install python-setuptools
 | 
					#   sudo apt-get install python-setuptools
 | 
				
			||||||
#   sudo easy_install -U transifex-client
 | 
					#   sudo easy_install -U transifex-client
 | 
				
			||||||
 | 
					
 | 
				
			||||||
PLUF_PATH=$(shell php -r "require_once('src/IDF/conf/path.php'); echo PLUF_PATH;")
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
all help:
 | 
					
 | 
				
			||||||
	@echo "Rules for generate tarball :"
 | 
					.PHONY: help
 | 
				
			||||||
 | 
					help:
 | 
				
			||||||
 | 
						@printf "Rules for generating distributable files :\n"
 | 
				
			||||||
	@for b in `git branch | sed "s/^. //g"`; do \
 | 
						@for b in `git branch | sed "s/^. //g"`; do \
 | 
				
			||||||
		echo -e "\t"$$b"_tarball - Generate a zip archive of the "$$b" branch."; \
 | 
							printf "\t"$$b"-zipfile - Generate a zip archive of the "$$b" branch.\n"; \
 | 
				
			||||||
	done
 | 
						done
 | 
				
			||||||
	@echo -e "\nRules for internationnalization :";
 | 
						@printf "\nRules for internationalization :\n";
 | 
				
			||||||
	@echo -e "\tpot-update - Update the POT file from HTML template and PHP source, then merge it with PO file"
 | 
						@printf "\tpot-update - Update the POT file from HTML templates and PHP sources, then merge it with PO file.\n"
 | 
				
			||||||
	@echo -e "\tpot-push - Send the POT file on transifex server"
 | 
						@printf "\tpot-push   - Send the POT file to the transifex server.\n"
 | 
				
			||||||
	@echo -e "\tpo-update - Merge POT file into PO file. POT is not regenerated."
 | 
						@printf "\tpo-update  - Merge the POT file into the PO file. The POT is not regenerated.\n"
 | 
				
			||||||
	@echo -e "\tpo-push - Send the all PO file on transifex server"
 | 
						@printf "\tpo-push    - Send the all PO files to the transifex server.\n"
 | 
				
			||||||
	@echo -e "\tpo-pull - Get all PO file from transifex server"
 | 
						@printf "\tpo-pull    - Get all PO files from the transifex server.\n"
 | 
				
			||||||
 | 
						@printf "\tpo-stats   - Show translation statistics of all PO files.\n"
 | 
				
			||||||
 | 
						@printf "\nMisc Rules :\n";
 | 
				
			||||||
 | 
						@printf "\tdb-install - Install the database schema.\n"
 | 
				
			||||||
 | 
						@printf "\tdb-update  - Update the database schema.\n"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
#   Internationnalization rule, POT & PO file manipulation
 | 
					#   Internationalization rule, POT & PO file manipulation
 | 
				
			||||||
#   
 | 
					#
 | 
				
			||||||
 | 
					.PHONY: pluf_path
 | 
				
			||||||
 | 
					pluf_path:
 | 
				
			||||||
 | 
					ifeq (src/IDF/conf/path.php, $(wildcard src/IDF/conf/path.php))
 | 
				
			||||||
 | 
					PLUF_PATH=$(shell php -r "require_once('src/IDF/conf/path.php'); echo PLUF_PATH;")
 | 
				
			||||||
 | 
					else
 | 
				
			||||||
 | 
						@printf "File 'src/IDF/conf/path.php' don't exist. Please configure it !\n"
 | 
				
			||||||
 | 
						@exit 1
 | 
				
			||||||
 | 
					endif
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
.PHONY: pot-update po-update
 | 
					.PHONY: pot-update po-update
 | 
				
			||||||
pot-update:
 | 
					pot-update: pluf_path
 | 
				
			||||||
	# Backup pot file
 | 
						# Backup pot file
 | 
				
			||||||
	@if [ -e src/IDF/locale/idf.pot ]; then                     \
 | 
						@if [ -e src/IDF/locale/idf.pot ]; then                     \
 | 
				
			||||||
	mv -f src/IDF/locale/idf.pot src/IDF/locale/idf.pot.bak;    \
 | 
						mv -f src/IDF/locale/idf.pot src/IDF/locale/idf.pot.bak;    \
 | 
				
			||||||
@@ -49,19 +64,20 @@ pot-update:
 | 
				
			|||||||
	# Extract string
 | 
						# Extract string
 | 
				
			||||||
	@cd src; php $(PLUF_PATH)/extracttemplates.php IDF/conf/idf.php IDF/gettexttemplates
 | 
						@cd src; php $(PLUF_PATH)/extracttemplates.php IDF/conf/idf.php IDF/gettexttemplates
 | 
				
			||||||
	@cd src; for phpfile in `find . -iname "*.php"`; do \
 | 
						@cd src; for phpfile in `find . -iname "*.php"`; do \
 | 
				
			||||||
		echo "Parsing file : "$$phpfile; \
 | 
							printf "Parsing file : "$$phpfile"\n"; \
 | 
				
			||||||
		xgettext -o idf.pot -p ./IDF/locale/ --from-code=UTF-8 -j --keyword --keyword=__ --keyword=_n:1,2 -L PHP $$phpfile ; \
 | 
							xgettext -o idf.pot -p ./IDF/locale/ --from-code=UTF-8 -j \
 | 
				
			||||||
 | 
								--keyword --keyword=__ --keyword=_n:1,2 -L PHP $$phpfile ; \
 | 
				
			||||||
		done
 | 
							done
 | 
				
			||||||
	#	Remove tmp folder
 | 
						#	Remove tmp folder
 | 
				
			||||||
	rm -Rf src/IDF/gettexttemplates
 | 
						rm -Rf src/IDF/gettexttemplates
 | 
				
			||||||
	# Update PO
 | 
						# Update PO
 | 
				
			||||||
	@make po-update
 | 
						@make po-update
 | 
				
			||||||
 | 
					
 | 
				
			||||||
po-update:
 | 
					po-update: pluf_path
 | 
				
			||||||
	@for pofile in `ls src/IDF/locale/*/idf.po`; do \
 | 
						@for pofile in `ls src/IDF/locale/*/idf.po`; do \
 | 
				
			||||||
		echo "Updating file : "$$pofile; \
 | 
							printf "Updating file : "$$pofile"\n"; \
 | 
				
			||||||
		msgmerge -v -U $$pofile src/IDF/locale/idf.pot; \
 | 
							msgmerge -v -U $$pofile src/IDF/locale/idf.pot; \
 | 
				
			||||||
		echo ; \
 | 
							printf "\n"; \
 | 
				
			||||||
	done
 | 
						done
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
@@ -72,22 +88,22 @@ check-tx-config:
 | 
				
			|||||||
	@if [ ! -e .tx/config ]; then                                       \
 | 
						@if [ ! -e .tx/config ]; then                                       \
 | 
				
			||||||
	mkdir -p .tx;                                                       \
 | 
						mkdir -p .tx;                                                       \
 | 
				
			||||||
	touch .tx/config;                                                   \
 | 
						touch .tx/config;                                                   \
 | 
				
			||||||
	echo "[main]" >> .tx/config;                                        \
 | 
						printf "[main]\n" >> .tx/config;                                        \
 | 
				
			||||||
	echo "host = http://www.transifex.net" >> .tx/config;               \
 | 
						printf "host = http://www.transifex.net\n" >> .tx/config;               \
 | 
				
			||||||
	echo "" >> .tx/config;                                              \
 | 
						printf "\n" >> .tx/config;                                              \
 | 
				
			||||||
	echo "[indefero.idfpot]" >> .tx/config;                             \
 | 
						printf "[indefero.idfpot]\n" >> .tx/config;                             \
 | 
				
			||||||
	echo "file_filter = src/IDF/locale/<lang>/idf.po" >> .tx/config;    \
 | 
						printf "file_filter = src/IDF/locale/<lang>/idf.po\n" >> .tx/config;    \
 | 
				
			||||||
	echo "source_file = src/IDF/locale/idf.pot" >> .tx/config;          \
 | 
						printf "source_file = src/IDF/locale/idf.pot\n" >> .tx/config;          \
 | 
				
			||||||
	echo "source_lang = en" >> .tx/config;                              \
 | 
						printf "source_lang = en\n" >> .tx/config;                              \
 | 
				
			||||||
	fi
 | 
						fi
 | 
				
			||||||
	@if [ ! -e $(HOME)/.transifexrc ]; then								\
 | 
						@if [ ! -e $(HOME)/.transifexrc ]; then					\
 | 
				
			||||||
	touch $(HOME)/.transifexrc;												\
 | 
						touch $(HOME)/.transifexrc;												\
 | 
				
			||||||
	echo "[http://www.transifex.net]" >> $(HOME)/.transifexrc;				\
 | 
						printf "[http://www.transifex.net]\n" >> $(HOME)/.transifexrc;						\
 | 
				
			||||||
	echo "username = " >> $(HOME)/.transifexrc;								\
 | 
						printf "username = \n" >> $(HOME)/.transifexrc;								\
 | 
				
			||||||
	echo "token = " >> $(HOME)/.transifexrc;									\
 | 
						printf "token = \n" >> $(HOME)/.transifexrc;								\
 | 
				
			||||||
	echo "password = " >> $(HOME)/.transifexrc;								\
 | 
						printf "password = \n" >> $(HOME)/.transifexrc;								\
 | 
				
			||||||
	echo "hostname = http://www.transifex.net" >> $(HOME)/.transifexrc;		\
 | 
						printf "hostname = http://www.transifex.net\n" >> $(HOME)/.transifexrc;					\
 | 
				
			||||||
	echo "You must edit the file ~/.transifexrc to setup your transifex account (login & password) !";		\
 | 
						printf "You must edit the file ~/.transifexrc to setup your transifex account (login & password) !\n";	\
 | 
				
			||||||
	exit 1;																\
 | 
						exit 1;																\
 | 
				
			||||||
	fi
 | 
						fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -98,13 +114,37 @@ po-push: check-tx-config
 | 
				
			|||||||
	@tx push -t
 | 
						@tx push -t
 | 
				
			||||||
 | 
					
 | 
				
			||||||
po-pull: check-tx-config
 | 
					po-pull: check-tx-config
 | 
				
			||||||
 | 
						# Save PO
 | 
				
			||||||
 | 
						@for pofile in `ls src/IDF/locale/*/idf.po`; do \
 | 
				
			||||||
 | 
						    cp $$pofile $$pofile".save"; \
 | 
				
			||||||
 | 
						done
 | 
				
			||||||
 | 
						# Get new one
 | 
				
			||||||
	@tx pull -a
 | 
						@tx pull -a
 | 
				
			||||||
 | 
						# Merge Transifex PO into local PO (so fuzzy entry is correctly saved)
 | 
				
			||||||
 | 
						@for pofile in `ls src/IDF/locale/*/idf.po`; do \
 | 
				
			||||||
 | 
						    msgmerge -U $$pofile".save" $$pofile; \
 | 
				
			||||||
 | 
						    rm -f $$pofile; \
 | 
				
			||||||
 | 
						    mv $$pofile".save" $$pofile; \
 | 
				
			||||||
 | 
						done
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					po-stats:
 | 
				
			||||||
 | 
						@msgfmt --statistics -v src/IDF/locale/idf.pot
 | 
				
			||||||
 | 
						@for pofile in `ls src/IDF/locale/*/idf.po`; do \
 | 
				
			||||||
 | 
						    msgfmt --statistics -v $$pofile; \
 | 
				
			||||||
 | 
						done
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
#   Generic rule to build a tarball of indefero for a specified branch
 | 
					#   Generic rule to build a zipfile of indefero for a specified branch
 | 
				
			||||||
#   ex: make master_tarball
 | 
					#   ex: make master_zipfile
 | 
				
			||||||
#       make dev_tarball
 | 
					#       make develop_zipfile
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
%_tarball:
 | 
					%-zipfile:
 | 
				
			||||||
	@git archive --format=zip --prefix="indefero/" $(@:_tarball=) > indefero-$(@:_tarball=)-`git log $(@:_tarball=) -n 1 --pretty=format:%H`.zip
 | 
						@git archive --format=zip --prefix="indefero/" $(@:-zipfile=) \
 | 
				
			||||||
 | 
							> indefero-$(@:-zipfile=)-`git log $(@:-zipfile=) -n 1 \
 | 
				
			||||||
 | 
							--pretty=format:%h`.zip
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					db-install:
 | 
				
			||||||
 | 
						@cd src && php $(PLUF_PATH)/migrate.php --conf=IDF/conf/idf.php -a -d -i
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					db-update:
 | 
				
			||||||
 | 
						@cd src && php $(PLUF_PATH)/migrate.php --conf=IDF/conf/idf.php -a -d
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										154
									
								
								NEWS.mdtext
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										154
									
								
								NEWS.mdtext
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,154 @@
 | 
				
			|||||||
 | 
					# InDefero 1.2 - xxx xxx xx xx:xx 2011 UTC
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ATTENTION: You need Pluf [324ae60b](http://projects.ceondo.com/p/pluf/source/commit/324ae60b)
 | 
				
			||||||
 | 
					or newer to properly run this version of Indefero!
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## New Features
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- Indefero's issue tracker can now bi-directionally link issues with variable, configurable
 | 
				
			||||||
 | 
					  terms, such as "is related to", "is blocked by" or "is duplicated by" (issue 638)
 | 
				
			||||||
 | 
					- Mercurial source views now show parent revisions (if any) and detailed change information
 | 
				
			||||||
 | 
					- Subversion source views now show detailed change information (issue 622)
 | 
				
			||||||
 | 
					- File download URLs now contain the file name rather than the upload id; old links still work though (issues 559 and 686)
 | 
				
			||||||
 | 
					- Display monotone file and directory attributes in the tree and file view
 | 
				
			||||||
 | 
					  (needs a monotone with an interface version of 13.1 or newer)
 | 
				
			||||||
 | 
					- The context area is now kept in view when a page scrolls down several pages
 | 
				
			||||||
 | 
					- git repositories are now available under /r/projectname/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Bugfixes
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- The SVN interface acts more robust if an underlying repository has been restructured (issues 364 and 721)
 | 
				
			||||||
 | 
					- monotone zip archive entries now all carry the revision date as mtime (issue 645)
 | 
				
			||||||
 | 
					- Timeline only displays filter options for items a user has actually access to (issue 655)
 | 
				
			||||||
 | 
					- The log, tags and branches parsers for Mercurial are more robust now (issue 663)
 | 
				
			||||||
 | 
					- Fix SSH public key parsing issues and improve the check for existing, uploaded keys (issue 679)
 | 
				
			||||||
 | 
					- Diff views now show empty context lines for git and hg again (issue 688)
 | 
				
			||||||
 | 
					- Let the SVN command line client not store the login credentials we give him as arguments
 | 
				
			||||||
 | 
					- The usher section in the forge administration no longer displays a bogus
 | 
				
			||||||
 | 
					  server enty in case no monotone server is configured in the connected
 | 
				
			||||||
 | 
					  usher instance
 | 
				
			||||||
 | 
					- Prevent a timeout from popping up when Usher is restarted (issue 695)
 | 
				
			||||||
 | 
					- The SyncMonotone plugin now cleans up partial artifacts it created during the addition of
 | 
				
			||||||
 | 
					  a new project or monotone key, in case an error popped up in the middle (issue 697)
 | 
				
			||||||
 | 
					- Indefero now sends the MD5 checksum as HTTP header when downloading a file from the
 | 
				
			||||||
 | 
					  download area. Additionally, a unneeded redirect has been removed. (issue 716)
 | 
				
			||||||
 | 
					- Better error detection and reporting in the SyncMonotone plugin
 | 
				
			||||||
 | 
					  ATTENTION: This needs Pluf 46b7f251 or newer!
 | 
				
			||||||
 | 
					- Fix the branch links users of the Subversion frontend get when they enter a wrong revision
 | 
				
			||||||
 | 
					  and only display this list if there are any branches available for all SCMs
 | 
				
			||||||
 | 
					- If git's author name is not encoded in an UTF-8 compatible encoding, skip the author lookup,
 | 
				
			||||||
 | 
					  as we have no information what the author string is actually encoded in
 | 
				
			||||||
 | 
					- Indefero no longer displays an empty parents paragraph in the commit view for root revisions of
 | 
				
			||||||
 | 
					  a git repository
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Documentation
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- The documentation on the setup of the monotone plugin has been improved.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Translations
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# InDefero 1.1.2 - Thu May 26 07:42:25 2011 UTC
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Bugfixes
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- Fix tags extraction from git repository (issue 675)
 | 
				
			||||||
 | 
					- Fix SSH validation method (issue 671)
 | 
				
			||||||
 | 
					- Fix malformed URL in the RSS (issue 666)
 | 
				
			||||||
 | 
					- Fix validateRevision call for Mercurial Scm (issue 657)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Translations
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- Missing word in French translation (issue 672)
 | 
				
			||||||
 | 
					- Update Spanish translation
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# InDefero 1.1.1 - Mon Mar 28 15:52 2011 UTC
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Bugfixes
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- Fix an incompatibility with Python 3.1 in gitserve.py (issue 554)
 | 
				
			||||||
 | 
					- Fix PHP error when the commit view shows a commit with changed binary files (issue 643)
 | 
				
			||||||
 | 
					- A migration problem prevented the preferences page being displayed properly (issues 644 and 653)
 | 
				
			||||||
 | 
					- Fix PHP error when trying to create Mercurial source archives (issue 648)
 | 
				
			||||||
 | 
					- Improve the French translation (issue 651)
 | 
				
			||||||
 | 
					- Registration page missed a link to password recovery that was mentioned in a form error (issue 652)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# InDefero 1.1 - Sun Mar 20 11:44 2011 UTC
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## New Features
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					* _Version control_:
 | 
				
			||||||
 | 
					 - Support for the monotone Version Control system (see [[InstallationScmMonotone]])
 | 
				
			||||||
 | 
					 - Display detailed changeset information in the commit details (git, mtn) (issue 544)
 | 
				
			||||||
 | 
					 - Show branch in the commit details (git, mtn, hg) (issue 450)
 | 
				
			||||||
 | 
					 - Render branch and tag names in a popup and make them filterable (git, hg, mtn) (issue 601)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					* _Issue tracking_:
 | 
				
			||||||
 | 
					 - Forge-wide and per-project watch lists of starred issues (issue 589)
 | 
				
			||||||
 | 
					 - Configure a default issue template for each project (issues 212 and 540)
 | 
				
			||||||
 | 
					 - Pick default issue labels from the configured project settings (issue 556)
 | 
				
			||||||
 | 
					 - Navigate to a preceding / following issue in the issue detail view
 | 
				
			||||||
 | 
					 - Many new text syntaxes to auto-link revisions (see [[AutomaticLinks]], issue 569)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					* _Documentation wiki_:
 | 
				
			||||||
 | 
					 - Automatically create a table of contents on wiki pages (issue 350)
 | 
				
			||||||
 | 
					 - Allow the usage of text labels for Wiki text links (issue 456)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					* _Other_:
 | 
				
			||||||
 | 
					 - Enhanced user profile page (issue 510)
 | 
				
			||||||
 | 
					 - Manage multiple (commit) emails in the account settings (issues 136 and 500)
 | 
				
			||||||
 | 
					 - Filter the timeline and its feed by item type (issue 543)
 | 
				
			||||||
 | 
					 - Add multiple email addresses for project notifications (issue 372)
 | 
				
			||||||
 | 
					 - Direct links to other projects via the new `Project List` dropdown
 | 
				
			||||||
 | 
					 - InDefero gained a favicon (issue 594)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Bugfixes
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- Fix `Need SSH_ORIGINAL_COMMAND in environment` error for git sync (issue 198)
 | 
				
			||||||
 | 
					- Added an option to disable lengthy project size calculation in the forge (issue 403)
 | 
				
			||||||
 | 
					- Fix a problem when deleting an orphaned git repository (issue 467)
 | 
				
			||||||
 | 
					- Ignore XML parsing problems when trying to retrieve commit messages for svn (issues 469 and 518)
 | 
				
			||||||
 | 
					- Sort the project list by the display name of the project (issue 477)
 | 
				
			||||||
 | 
					- Project creation form now has a short description field as well (issue 479)
 | 
				
			||||||
 | 
					- Add more file extensions supported by our in-tree prettify version (issues 490 and 567)
 | 
				
			||||||
 | 
					- Improve the parsing of hg's log output (issues 507 and 508)
 | 
				
			||||||
 | 
					- Do not clean `<ins>` and `<del>` HTML markup from user input (issue 509)
 | 
				
			||||||
 | 
					- Improve HTML validation by switching from `strict` to `transitional` DOCTYPE (issue 511)
 | 
				
			||||||
 | 
					- Properly handle git commits without a changelog title (issue 520)
 | 
				
			||||||
 | 
					- Improve BSD compatibility in shell scripts (issue 526)
 | 
				
			||||||
 | 
					- Properly render inner whitespaces in viewed issue attachments (issue 528)
 | 
				
			||||||
 | 
					- Support for uploading SSH keys without optional comment (issue 531)
 | 
				
			||||||
 | 
					- Recognize irc: and git: protocols in Markdown renderer (issue 546)
 | 
				
			||||||
 | 
					- New config option `git_core_quotepath` to handle non-ASCII git file names (issue 553)
 | 
				
			||||||
 | 
					- Ensured that active views are rendered in the menu as such (issue 555)
 | 
				
			||||||
 | 
					- Add CSS for nested and mixed ordered and unordered lists (issue 557)
 | 
				
			||||||
 | 
					- Directories are now sorted before files in source tree views (issue 573)
 | 
				
			||||||
 | 
					- File attachments now have explicit view and download links in issue views (issue 575)
 | 
				
			||||||
 | 
					- Display anonymous access URL when user has no SSH key registered (issue 588)
 | 
				
			||||||
 | 
					- Improve the rendering of tag lists in issue views (issue 591)
 | 
				
			||||||
 | 
					- Improved error page when a commit or branch was not found (issue 609)
 | 
				
			||||||
 | 
					- Disable browser autocomplete of password fields in the account settings (issue 616)
 | 
				
			||||||
 | 
					- Improvements in the automatic linker parser (issue 618)
 | 
				
			||||||
 | 
					- The `createIssue` API method did not check the API authentication (issue 619)
 | 
				
			||||||
 | 
					- Reduce the memory footprint and compatibility of the internal diff parser (issues 627 and 633)
 | 
				
			||||||
 | 
					- Print the git branches and tags in bold which contain the currently displayed revision
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Documentation
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- Document how to contribute to Indefero in `CONTRIBUTE.mdtext` (issue 486)
 | 
				
			||||||
 | 
					- Note possible problems with mbstring.func_overload in `INSTALL.mdtext` (issue 481)
 | 
				
			||||||
 | 
					- Improve links to Markdown documentation (issue 489)
 | 
				
			||||||
 | 
					- Explain purpose of `idf_strong_key_check` in `idf.php-dist` (issue 516)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Translations
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- Spanish translation added
 | 
				
			||||||
 | 
					- Started with a Simplified Chinese translation (issue 521)
 | 
				
			||||||
 | 
					- Started with a Russian translation
 | 
				
			||||||
 | 
					- Updates and fixes to the French translation (issue 574)
 | 
				
			||||||
 | 
					- Updates and fixes to the German translation
 | 
				
			||||||
 | 
					- English source language has been improved (issues 441, 478, and 631)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# InDefero 1.0 - Tue Apr 20 07:00 2010 UTC
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					First stable release.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										57
									
								
								doc/httprepos-git.mdtext
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								doc/httprepos-git.mdtext
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,57 @@
 | 
				
			|||||||
 | 
					# Accessing git repositories over HTTP
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Starting with indefero 1.2, git repositories are provided via http,
 | 
				
			||||||
 | 
					featuring read-only and read-write access with full integration with
 | 
				
			||||||
 | 
					indefero's access control mechanisms.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Access git repositories
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The repositories are available under http://YOURHOST/BASEPATH/r/PROJECT.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					For authentication, use the "extra password" which you can find on your
 | 
				
			||||||
 | 
					profile page.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Setup
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The main thing to setup is git_repositories and git_remote_url in
 | 
				
			||||||
 | 
					src/IDF/conf/idf.php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					git_remote_url should match http://YOURHOST/BASEPATH/r/%s, while
 | 
				
			||||||
 | 
					git_repositories points to the local directory supposed to contain the
 | 
				
			||||||
 | 
					repositories like /PATH/TO/REPOSITORIES/%s.git.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Setup requirements when using PHP over FastCGI
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					There are a couple of things to setup when using PHP over FastCGI, as compared
 | 
				
			||||||
 | 
					to mod_php or similar integrated mechanisms:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- You will need to setup a RewriteRule for mod_rewrite (in case of Apache,
 | 
				
			||||||
 | 
					  analogous mechanisms might need to be setup for other http daemons), which
 | 
				
			||||||
 | 
					  passes through the Authorization HTTP Header of a request.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  In case of mod_rewrite, the necessary line is
 | 
				
			||||||
 | 
					  one of (depending on server configuration):
 | 
				
			||||||
 | 
					      RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization},L]
 | 
				
			||||||
 | 
					      RewriteRule .* - [E=REMOTE_USER:%{HTTP:Authorization},L]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- The FastCGI adaptor must allow large requests to be handled by PHP,
 | 
				
			||||||
 | 
					  otherwise push might fail.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  For mod_fcgid, this is the FcgidMaxRequestLen option, or MaxRequestLen in
 | 
				
			||||||
 | 
					  older versions. Set this option to some large enough value - there is no
 | 
				
			||||||
 | 
					  issue with RAM use, as another option defines the limit after which the
 | 
				
			||||||
 | 
					  request is backed on disk, which can remain small.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## When migrating from syncgit
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					HTTP access can be used in parallel to syncgit.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					If you want to disable syncgit, just undo the changes detailled
 | 
				
			||||||
 | 
					in doc/syncgit.mdtext:
 | 
				
			||||||
 | 
					- In src/IDF/conf/idf.php keep git_repositories
 | 
				
			||||||
 | 
					- In src/IDF/conf/idf.php adapt git_remote_url to http://host/basepath/r/%s 
 | 
				
			||||||
 | 
					- In src/IDF/conf/idf.php remove idf_plugin_syncgit*
 | 
				
			||||||
 | 
					- Remove the cronjob that called gitcron.php
 | 
				
			||||||
 | 
					- Disable the git daemon (eg. /etc/event.d/local-git-daemon)
 | 
				
			||||||
 | 
					- You can remove the git user and group, if you also adapt the git repositories
 | 
				
			||||||
 | 
					  to be owned by the www user.
 | 
				
			||||||
@@ -25,7 +25,7 @@ If you install monotone from source (<http://monotone.ca/downloads.php>),
 | 
				
			|||||||
please follow the `INSTALL` document which comes with the software.
 | 
					please follow the `INSTALL` document which comes with the software.
 | 
				
			||||||
It contains detailed instructions, including all needed dependencies.
 | 
					It contains detailed instructions, including all needed dependencies.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## Choose your indefero setup
 | 
					## Choose your indefero (IDF) setup
 | 
				
			||||||
 | 
					
 | 
				
			||||||
The monotone plugin can be used in several different ways:
 | 
					The monotone plugin can be used in several different ways:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -112,14 +112,40 @@ The monotone plugin can be used in several different ways:
 | 
				
			|||||||
            ^D
 | 
					            ^D
 | 
				
			||||||
            $ chmod 600 usher.conf
 | 
					            $ chmod 600 usher.conf
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    **ATTENTION:** Do _not_ configure a default monotone server key in `usher.conf`,
 | 
				
			||||||
 | 
					    otherwise the individual server key that IDF creates for each project is
 | 
				
			||||||
 | 
					    not used and this could cause problems.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Your indefero www user needs later write access to `usher.conf` and
 | 
					    Your indefero www user needs later write access to `usher.conf` and
 | 
				
			||||||
    `projects/`. There are two ways of setting this up:
 | 
					    `projects/`. There are two ways of setting this up:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    * Make the usher user the web user, for example via Apache's `suexec`
 | 
					    * Make the usher user the web user, for example via Apache's `suexec`.
 | 
				
			||||||
    * Use acls, like this:
 | 
					      This is however a bit clumsy.
 | 
				
			||||||
 | 
					    * Preferred: Use Access Control Lists (ACLs), like this:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            #
 | 
				
			||||||
 | 
					            # Linux
 | 
				
			||||||
 | 
					            #
 | 
				
			||||||
            $ setfacl -m u:www:rw usher.conf
 | 
					            $ setfacl -m u:www:rw usher.conf
 | 
				
			||||||
            $ setfacl -m d:u:www:rwx projects/
 | 
					            $ setfacl -m d:u:www:rwx projects/
 | 
				
			||||||
 | 
					            $ setfacl -m d:u:usher:rwx projects/
 | 
				
			||||||
 | 
					            #
 | 
				
			||||||
 | 
					            # FreeBSD
 | 
				
			||||||
 | 
					            #
 | 
				
			||||||
 | 
					            $ setfacl -m user:www:rw::allow usher.conf
 | 
				
			||||||
 | 
					            $ setfacl -m user:www:rwxp:fd:allow projects/
 | 
				
			||||||
 | 
					            $ setfacl -m user:usher:rwxp:fd:allow projects/
 | 
				
			||||||
 | 
					            #
 | 
				
			||||||
 | 
					            # Mac OS X
 | 
				
			||||||
 | 
					            #
 | 
				
			||||||
 | 
					            chmod +a '_www allow read,write' usher.conf
 | 
				
			||||||
 | 
					            chmod +a '_www allow read,write,delete,add_file,add_subdirectory,file_inherit,directory_inherit' projects/
 | 
				
			||||||
 | 
					            chmod +a 'usher allow read,write,delete,add_file,add_subdirectory,file_inherit,directory_inherit' projects/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      In each example's last line, `usher` is the user which is executing
 | 
				
			||||||
 | 
					      the usher instance. **It is very important to add this line, otherwise
 | 
				
			||||||
 | 
					      usher won't be able to read and write into the initial file system
 | 
				
			||||||
 | 
					      setup IDF creates!**
 | 
				
			||||||
 | 
					
 | 
				
			||||||
5. Wrap a daemonizer around usher, for example supervise from daemontools
 | 
					5. Wrap a daemonizer around usher, for example supervise from daemontools
 | 
				
			||||||
   (<http://cr.yp.to/damontools.html>):
 | 
					   (<http://cr.yp.to/damontools.html>):
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										173
									
								
								logo/no_logo.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										173
									
								
								logo/no_logo.svg
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,173 @@
 | 
				
			|||||||
 | 
					<?xml version="1.0" encoding="UTF-8" standalone="no"?>
 | 
				
			||||||
 | 
					<!-- Created with Inkscape (http://www.inkscape.org/) -->
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<svg
 | 
				
			||||||
 | 
					   xmlns:dc="http://purl.org/dc/elements/1.1/"
 | 
				
			||||||
 | 
					   xmlns:cc="http://creativecommons.org/ns#"
 | 
				
			||||||
 | 
					   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
 | 
				
			||||||
 | 
					   xmlns:svg="http://www.w3.org/2000/svg"
 | 
				
			||||||
 | 
					   xmlns="http://www.w3.org/2000/svg"
 | 
				
			||||||
 | 
					   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
 | 
				
			||||||
 | 
					   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
 | 
				
			||||||
 | 
					   sodipodi:docname="no_logo.svg"
 | 
				
			||||||
 | 
					   inkscape:version="0.47 r22583"
 | 
				
			||||||
 | 
					   id="svg2985"
 | 
				
			||||||
 | 
					   height="32"
 | 
				
			||||||
 | 
					   width="32"
 | 
				
			||||||
 | 
					   version="1.1"
 | 
				
			||||||
 | 
					   inkscape:export-filename="/Users/tommyd/Entwicklung/indefero/www/media/idf/img/no_logo.png"
 | 
				
			||||||
 | 
					   inkscape:export-xdpi="89.989998"
 | 
				
			||||||
 | 
					   inkscape:export-ydpi="89.989998">
 | 
				
			||||||
 | 
					  <sodipodi:namedview
 | 
				
			||||||
 | 
					     pagecolor="#ffffff"
 | 
				
			||||||
 | 
					     bordercolor="#666666"
 | 
				
			||||||
 | 
					     borderopacity="1"
 | 
				
			||||||
 | 
					     objecttolerance="10"
 | 
				
			||||||
 | 
					     gridtolerance="10"
 | 
				
			||||||
 | 
					     guidetolerance="10"
 | 
				
			||||||
 | 
					     inkscape:pageopacity="0"
 | 
				
			||||||
 | 
					     inkscape:pageshadow="2"
 | 
				
			||||||
 | 
					     inkscape:window-width="1440"
 | 
				
			||||||
 | 
					     inkscape:window-height="852"
 | 
				
			||||||
 | 
					     id="namedview9"
 | 
				
			||||||
 | 
					     showgrid="false"
 | 
				
			||||||
 | 
					     inkscape:zoom="16.0625"
 | 
				
			||||||
 | 
					     inkscape:cx="8.5507561"
 | 
				
			||||||
 | 
					     inkscape:cy="16.122403"
 | 
				
			||||||
 | 
					     inkscape:window-x="0"
 | 
				
			||||||
 | 
					     inkscape:window-y="0"
 | 
				
			||||||
 | 
					     inkscape:window-maximized="0"
 | 
				
			||||||
 | 
					     inkscape:current-layer="g2847"
 | 
				
			||||||
 | 
					     showguides="true"
 | 
				
			||||||
 | 
					     inkscape:guide-bbox="true">
 | 
				
			||||||
 | 
					    <sodipodi:guide
 | 
				
			||||||
 | 
					       orientation="1,0"
 | 
				
			||||||
 | 
					       position="16,25.836575"
 | 
				
			||||||
 | 
					       id="guide3752" />
 | 
				
			||||||
 | 
					    <sodipodi:guide
 | 
				
			||||||
 | 
					       orientation="0,1"
 | 
				
			||||||
 | 
					       position="-18.677042,16"
 | 
				
			||||||
 | 
					       id="guide3754" />
 | 
				
			||||||
 | 
					  </sodipodi:namedview>
 | 
				
			||||||
 | 
					  <defs
 | 
				
			||||||
 | 
					     id="defs2987">
 | 
				
			||||||
 | 
					    <inkscape:perspective
 | 
				
			||||||
 | 
					       sodipodi:type="inkscape:persp3d"
 | 
				
			||||||
 | 
					       inkscape:vp_x="0 : 16 : 1"
 | 
				
			||||||
 | 
					       inkscape:vp_y="0 : 1000 : 0"
 | 
				
			||||||
 | 
					       inkscape:vp_z="32 : 16 : 1"
 | 
				
			||||||
 | 
					       inkscape:persp3d-origin="16 : 10.666667 : 1"
 | 
				
			||||||
 | 
					       id="perspective13" />
 | 
				
			||||||
 | 
					    <inkscape:perspective
 | 
				
			||||||
 | 
					       id="perspective2863"
 | 
				
			||||||
 | 
					       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
 | 
				
			||||||
 | 
					       inkscape:vp_z="1 : 0.5 : 1"
 | 
				
			||||||
 | 
					       inkscape:vp_y="0 : 1000 : 0"
 | 
				
			||||||
 | 
					       inkscape:vp_x="0 : 0.5 : 1"
 | 
				
			||||||
 | 
					       sodipodi:type="inkscape:persp3d" />
 | 
				
			||||||
 | 
					    <inkscape:perspective
 | 
				
			||||||
 | 
					       id="perspective3676"
 | 
				
			||||||
 | 
					       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
 | 
				
			||||||
 | 
					       inkscape:vp_z="1 : 0.5 : 1"
 | 
				
			||||||
 | 
					       inkscape:vp_y="0 : 1000 : 0"
 | 
				
			||||||
 | 
					       inkscape:vp_x="0 : 0.5 : 1"
 | 
				
			||||||
 | 
					       sodipodi:type="inkscape:persp3d" />
 | 
				
			||||||
 | 
					    <inkscape:perspective
 | 
				
			||||||
 | 
					       id="perspective3717"
 | 
				
			||||||
 | 
					       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
 | 
				
			||||||
 | 
					       inkscape:vp_z="1 : 0.5 : 1"
 | 
				
			||||||
 | 
					       inkscape:vp_y="0 : 1000 : 0"
 | 
				
			||||||
 | 
					       inkscape:vp_x="0 : 0.5 : 1"
 | 
				
			||||||
 | 
					       sodipodi:type="inkscape:persp3d" />
 | 
				
			||||||
 | 
					    <filter
 | 
				
			||||||
 | 
					       inkscape:collect="always"
 | 
				
			||||||
 | 
					       id="filter3816"
 | 
				
			||||||
 | 
					       x="-0.14434362"
 | 
				
			||||||
 | 
					       width="1.2886872"
 | 
				
			||||||
 | 
					       y="-0.11562817"
 | 
				
			||||||
 | 
					       height="1.2312563">
 | 
				
			||||||
 | 
					      <feGaussianBlur
 | 
				
			||||||
 | 
					         inkscape:collect="always"
 | 
				
			||||||
 | 
					         stdDeviation="1.1799243"
 | 
				
			||||||
 | 
					         id="feGaussianBlur3818" />
 | 
				
			||||||
 | 
					    </filter>
 | 
				
			||||||
 | 
					  </defs>
 | 
				
			||||||
 | 
					  <metadata
 | 
				
			||||||
 | 
					     id="metadata2990">
 | 
				
			||||||
 | 
					    <rdf:RDF>
 | 
				
			||||||
 | 
					      <cc:Work
 | 
				
			||||||
 | 
					         rdf:about="">
 | 
				
			||||||
 | 
					        <dc:format>image/svg+xml</dc:format>
 | 
				
			||||||
 | 
					        <dc:type
 | 
				
			||||||
 | 
					           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
 | 
				
			||||||
 | 
					        <dc:title></dc:title>
 | 
				
			||||||
 | 
					      </cc:Work>
 | 
				
			||||||
 | 
					    </rdf:RDF>
 | 
				
			||||||
 | 
					  </metadata>
 | 
				
			||||||
 | 
					  <g
 | 
				
			||||||
 | 
					     inkscape:groupmode="layer"
 | 
				
			||||||
 | 
					     id="layer2"
 | 
				
			||||||
 | 
					     inkscape:label="shadow"
 | 
				
			||||||
 | 
					     style="display:inline"
 | 
				
			||||||
 | 
					     sodipodi:insensitive="true">
 | 
				
			||||||
 | 
					    <g
 | 
				
			||||||
 | 
					       transform="translate(0.44042901,0.78704792)"
 | 
				
			||||||
 | 
					       id="g2847-8"
 | 
				
			||||||
 | 
					       style="opacity:0.79710143;fill:#000000;stroke:#000000;stroke-opacity:1;filter:url(#filter3816)">
 | 
				
			||||||
 | 
					      <g
 | 
				
			||||||
 | 
					         id="g3838-0"
 | 
				
			||||||
 | 
					         style="fill:#000000;stroke:#000000;stroke-opacity:1" />
 | 
				
			||||||
 | 
					      <g
 | 
				
			||||||
 | 
					         id="g2401-2"
 | 
				
			||||||
 | 
					         transform="matrix(0.21219597,0,0,0.21219597,-70.751966,-27.73328)"
 | 
				
			||||||
 | 
					         style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:2.4000001;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
 | 
				
			||||||
 | 
					         inkscape:export-filename="/home/loa/Projects/indefero/logo/powered-by-indefero.png"
 | 
				
			||||||
 | 
					         inkscape:export-xdpi="12.330909"
 | 
				
			||||||
 | 
					         inkscape:export-ydpi="12.330909">
 | 
				
			||||||
 | 
					        <path
 | 
				
			||||||
 | 
					           id="path2383-4"
 | 
				
			||||||
 | 
					           d="m 396.19089,173.14471 c -7.67621,0.80661 -14.40195,5.39406 -19.58101,10.89131 -7.23597,7.88004 -11.69742,18.07908 -13.32198,28.60362 -1.7236,11.28173 -0.25925,23.20635 5.07686,33.37271 3.78607,7.24384 9.53161,13.92339 17.29701,16.96772 3.86478,1.53937 8.98362,1.03284 11.67912,-2.41036 2.64357,-3.5671 2.69463,-8.234 2.85756,-12.48867 0.045,-7.61054 -0.54749,-15.25544 0.45618,-22.83193 0.87131,-9.50623 4.03944,-18.56751 6.71612,-27.66851 1.16242,-4.44333 2.25094,-9.02808 1.97499,-13.64988 -0.48817,-4.62476 -3.58059,-9.31042 -8.2964,-10.4067 -1.57489,-0.44882 -3.23412,-0.48948 -4.85845,-0.37931 z"
 | 
				
			||||||
 | 
					           style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:2.4000001;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
 | 
				
			||||||
 | 
					           inkscape:connector-curvature="0" />
 | 
				
			||||||
 | 
					        <path
 | 
				
			||||||
 | 
					           id="path2391-8"
 | 
				
			||||||
 | 
					           d="m 433.14691,149.28687 c 7.2059,2.76589 12.51512,8.93778 16.09494,15.58815 4.94991,9.48434 6.61962,20.49058 5.46486,31.07695 -1.25505,11.34342 -5.75582,22.48271 -13.54134,30.92159 -5.53192,6.01709 -12.81048,10.98198 -21.09918,11.91276 -4.13154,0.4866 -8.94486,-1.32748 -10.65734,-5.35104 -1.63027,-4.12976 -0.4717,-8.65084 0.47212,-12.80269 1.92628,-7.36287 4.47721,-14.59393 5.4687,-22.17201 1.61875,-9.40784 0.90381,-18.98034 0.67386,-28.46402 0.0272,-4.59278 0.1624,-9.30303 1.62515,-13.69592 1.66851,-4.34082 5.86829,-8.06645 10.70716,-7.90484 1.63738,-0.0259 3.25061,0.36424 4.79107,0.89107 z"
 | 
				
			||||||
 | 
					           style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:2.4000001;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
 | 
				
			||||||
 | 
					           inkscape:connector-curvature="0" />
 | 
				
			||||||
 | 
					      </g>
 | 
				
			||||||
 | 
					    </g>
 | 
				
			||||||
 | 
					  </g>
 | 
				
			||||||
 | 
					  <g
 | 
				
			||||||
 | 
					     inkscape:groupmode="layer"
 | 
				
			||||||
 | 
					     id="layer3"
 | 
				
			||||||
 | 
					     inkscape:label="logo"
 | 
				
			||||||
 | 
					     style="display:inline">
 | 
				
			||||||
 | 
					    <g
 | 
				
			||||||
 | 
					       id="layer1"
 | 
				
			||||||
 | 
					       transform="translate(-0.06540759,0.09444087)">
 | 
				
			||||||
 | 
					      <g
 | 
				
			||||||
 | 
					         id="g2847">
 | 
				
			||||||
 | 
					        <g
 | 
				
			||||||
 | 
					           id="g3838" />
 | 
				
			||||||
 | 
					        <g
 | 
				
			||||||
 | 
					           id="g2401"
 | 
				
			||||||
 | 
					           transform="matrix(0.21219597,0,0,0.21219597,-70.751966,-27.73328)"
 | 
				
			||||||
 | 
					           style="fill:#e6e6e6;fill-opacity:1;stroke:#a0a0a0;stroke-width:2.4000001;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
 | 
				
			||||||
 | 
					           inkscape:export-filename="/home/loa/Projects/indefero/logo/powered-by-indefero.png"
 | 
				
			||||||
 | 
					           inkscape:export-xdpi="12.330909"
 | 
				
			||||||
 | 
					           inkscape:export-ydpi="12.330909">
 | 
				
			||||||
 | 
					          <path
 | 
				
			||||||
 | 
					             id="path2383"
 | 
				
			||||||
 | 
					             d="m 396.19089,173.14471 c -7.67621,0.80661 -14.40195,5.39406 -19.58101,10.89131 -7.23597,7.88004 -11.69742,18.07908 -13.32198,28.60362 -1.7236,11.28173 -0.25925,23.20635 5.07686,33.37271 3.78607,7.24384 9.53161,13.92339 17.29701,16.96772 3.86478,1.53937 8.98362,1.03284 11.67912,-2.41036 2.64357,-3.5671 2.69463,-8.234 2.85756,-12.48867 0.045,-7.61054 -0.54749,-15.25544 0.45618,-22.83193 0.87131,-9.50623 4.03944,-18.56751 6.71612,-27.66851 1.16242,-4.44333 2.25094,-9.02808 1.97499,-13.64988 -0.48817,-4.62476 -3.58059,-9.31042 -8.2964,-10.4067 -1.57489,-0.44882 -3.23412,-0.48948 -4.85845,-0.37931 z"
 | 
				
			||||||
 | 
					             style="fill:#e6e6e6;fill-opacity:1;fill-rule:nonzero;stroke:#a0a0a0;stroke-width:2.4000001;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
 | 
				
			||||||
 | 
					             inkscape:connector-curvature="0" />
 | 
				
			||||||
 | 
					          <path
 | 
				
			||||||
 | 
					             id="path2391"
 | 
				
			||||||
 | 
					             d="m 433.14691,149.28687 c 7.2059,2.76589 12.51512,8.93778 16.09494,15.58815 4.94991,9.48434 6.61962,20.49058 5.46486,31.07695 -1.25505,11.34342 -5.75582,22.48271 -13.54134,30.92159 -5.53192,6.01709 -12.81048,10.98198 -21.09918,11.91276 -4.13154,0.4866 -8.94486,-1.32748 -10.65734,-5.35104 -1.63027,-4.12976 -0.4717,-8.65084 0.47212,-12.80269 1.92628,-7.36287 4.47721,-14.59393 5.4687,-22.17201 1.61875,-9.40784 0.90381,-18.98034 0.67386,-28.46402 0.0272,-4.59278 0.1624,-9.30303 1.62515,-13.69592 1.66851,-4.34082 5.86829,-8.06645 10.70716,-7.90484 1.63738,-0.0259 3.25061,0.36424 4.79107,0.89107 z"
 | 
				
			||||||
 | 
					             style="fill:#e6e6e6;fill-opacity:1;fill-rule:nonzero;stroke:#a0a0a0;stroke-width:2.4000001;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
 | 
				
			||||||
 | 
					             inkscape:connector-curvature="0" />
 | 
				
			||||||
 | 
					        </g>
 | 
				
			||||||
 | 
					      </g>
 | 
				
			||||||
 | 
					    </g>
 | 
				
			||||||
 | 
					  </g>
 | 
				
			||||||
 | 
					</svg>
 | 
				
			||||||
| 
		 After Width: | Height: | Size: 8.4 KiB  | 
							
								
								
									
										27
									
								
								phpunit.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								phpunit.xml
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,27 @@
 | 
				
			|||||||
 | 
					<phpunit backupGlobals="true"
 | 
				
			||||||
 | 
					         backupStaticAttributes="false"
 | 
				
			||||||
 | 
					         bootstrap="test/bootstrap.php"
 | 
				
			||||||
 | 
					         convertErrorsToExceptions="true"
 | 
				
			||||||
 | 
					         convertNoticesToExceptions="true"
 | 
				
			||||||
 | 
					         convertWarningsToExceptions="true"
 | 
				
			||||||
 | 
					         strict="false"
 | 
				
			||||||
 | 
					         verbose="true">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <testsuites>
 | 
				
			||||||
 | 
					        <testsuite name="Everything">
 | 
				
			||||||
 | 
					            <directory>test/IDF/</directory>
 | 
				
			||||||
 | 
					        </testsuite>
 | 
				
			||||||
 | 
					    </testsuites>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <filter>
 | 
				
			||||||
 | 
					        <whitelist>
 | 
				
			||||||
 | 
					            <directory suffix=".php">src/IDF</directory>
 | 
				
			||||||
 | 
					            <exclude>
 | 
				
			||||||
 | 
					                <directory suffix=".php">src/IDF/Tests</directory>
 | 
				
			||||||
 | 
					                <directory suffix=".php">src/IDF/conf</directory>
 | 
				
			||||||
 | 
					                <file>src/IDF/version.php</file>
 | 
				
			||||||
 | 
					            </exclude>
 | 
				
			||||||
 | 
					        </whitelist>
 | 
				
			||||||
 | 
					    </filter>
 | 
				
			||||||
 | 
					</phpunit>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										14
									
								
								run-tests
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										14
									
								
								run-tests
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,14 @@
 | 
				
			|||||||
 | 
					#!/usr/bin/env php
 | 
				
			||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					$xmlfile = dirname(__FILE__) .'/test/report.xml';
 | 
				
			||||||
 | 
					passthru('phpunit --coverage-clover='.$xmlfile);
 | 
				
			||||||
 | 
					$xml = simplexml_load_string(file_get_contents($xmlfile));
 | 
				
			||||||
 | 
					unlink($xmlfile);
 | 
				
			||||||
 | 
					printf(
 | 
				
			||||||
 | 
					   '>>> code coverage %s/%s (%s%%)'."\n",
 | 
				
			||||||
 | 
					   $xml->project->metrics['coveredstatements'],
 | 
				
			||||||
 | 
					   $xml->project->metrics['statements'],
 | 
				
			||||||
 | 
					   round(($xml->project->metrics['coveredstatements']/(float)$xml->project->metrics['statements']) * 100.0, 2)
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -3,7 +3,7 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
# ***** BEGIN LICENSE BLOCK *****
 | 
					# ***** BEGIN LICENSE BLOCK *****
 | 
				
			||||||
# This file is part of InDefero, an open source project management application.
 | 
					# This file is part of InDefero, an open source project management application.
 | 
				
			||||||
# Copyright (C) 2008 Céondo Ltd and contributors.
 | 
					# Copyright (C) 2008-2011 Céondo Ltd and contributors.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# InDefero is free software; you can redistribute it and/or modify
 | 
					# InDefero is free software; you can redistribute it and/or modify
 | 
				
			||||||
# it under the terms of the GNU General Public License as published by
 | 
					# it under the terms of the GNU General Public License as published by
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,7 +3,7 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
# ***** BEGIN LICENSE BLOCK *****
 | 
					# ***** BEGIN LICENSE BLOCK *****
 | 
				
			||||||
# This file is part of InDefero, an open source project management application.
 | 
					# This file is part of InDefero, an open source project management application.
 | 
				
			||||||
# Copyright (C) 2008-2010 Céondo Ltd and contributors.
 | 
					# Copyright (C) 2008-2011 Céondo Ltd and contributors.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# InDefero is free software; you can redistribute it and/or modify
 | 
					# InDefero is free software; you can redistribute it and/or modify
 | 
				
			||||||
# it under the terms of the GNU General Public License as published by
 | 
					# it under the terms of the GNU General Public License as published by
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,7 +3,7 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
# ***** BEGIN LICENSE BLOCK *****
 | 
					# ***** BEGIN LICENSE BLOCK *****
 | 
				
			||||||
# This file is part of InDefero, an open source project management application.
 | 
					# This file is part of InDefero, an open source project management application.
 | 
				
			||||||
# Copyright (C) 2008 Céondo Ltd and contributors.
 | 
					# Copyright (C) 2008-2011 Céondo Ltd and contributors.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# InDefero is free software; you can redistribute it and/or modify
 | 
					# InDefero is free software; you can redistribute it and/or modify
 | 
				
			||||||
# it under the terms of the GNU General Public License as published by
 | 
					# it under the terms of the GNU General Public License as published by
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,9 +1,9 @@
 | 
				
			|||||||
#!/usr/bin/env python
 | 
					#!/usr/bin/env python
 | 
				
			||||||
# -*- coding: utf-8 -*-
 | 
					# -*- coding: utf-8 -*-
 | 
				
			||||||
# 
 | 
					#
 | 
				
			||||||
# ***** BEGIN LICENSE BLOCK *****
 | 
					# ***** BEGIN LICENSE BLOCK *****
 | 
				
			||||||
# This file is part of InDefero, an open source project management application.
 | 
					# This file is part of InDefero, an open source project management application.
 | 
				
			||||||
# Copyright (C) 2008 Céondo Ltd and contributors.
 | 
					# Copyright (C) 2008-2011 Céondo Ltd and contributors.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# InDefero is free software; you can redistribute it and/or modify
 | 
					# InDefero is free software; you can redistribute it and/or modify
 | 
				
			||||||
# it under the terms of the GNU General Public License as published by
 | 
					# it under the terms of the GNU General Public License as published by
 | 
				
			||||||
@@ -23,14 +23,17 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import os
 | 
					import os
 | 
				
			||||||
import sys
 | 
					import sys
 | 
				
			||||||
import commands
 | 
					import subprocess
 | 
				
			||||||
import traceback
 | 
					
 | 
				
			||||||
 | 
					SCRIPTDIR = os.path.abspath(__file__).rsplit(os.path.sep, 1)[0]
 | 
				
			||||||
 | 
					GITSERVEPHP = '%s/gitserve.php' % SCRIPTDIR
 | 
				
			||||||
 | 
					process = subprocess.Popen(['php', GITSERVEPHP, sys.argv[1]],
 | 
				
			||||||
 | 
					                stdout=subprocess.PIPE, stderr=subprocess.PIPE)
 | 
				
			||||||
 | 
					output = str.encode("\n").join(process.communicate()).strip()
 | 
				
			||||||
 | 
					status = process.wait()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
n = len("/gitserve.py")
 | 
					 | 
				
			||||||
GITSERVEPHP = '%s/gitserve.php' % traceback.extract_stack(limit=1)[0][0][0:-n]
 | 
					 | 
				
			||||||
status, output = commands.getstatusoutput('php %s %s' % (GITSERVEPHP, sys.argv[1]))
 | 
					 | 
				
			||||||
if status == 0:
 | 
					if status == 0:
 | 
				
			||||||
    os.execvp('git', ['git', 'shell', '-c', output.strip()])
 | 
					    os.execvp('git', ['git', 'shell', '-c', output.strip()])
 | 
				
			||||||
else:
 | 
					else:
 | 
				
			||||||
    sys.stderr.write("%s\n" % output)
 | 
					    sys.stderr.write("%s\n" % output.strip())
 | 
				
			||||||
sys.exit(1)
 | 
					sys.exit(1)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,7 +4,7 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
# ***** BEGIN LICENSE BLOCK *****
 | 
					# ***** BEGIN LICENSE BLOCK *****
 | 
				
			||||||
# This file is part of InDefero, an open source project management application.
 | 
					# This file is part of InDefero, an open source project management application.
 | 
				
			||||||
# Copyright (C) 2008-2010 Céondo Ltd and contributors.
 | 
					# Copyright (C) 2008-2011 Céondo Ltd and contributors.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# InDefero is free software; you can redistribute it and/or modify
 | 
					# InDefero is free software; you can redistribute it and/or modify
 | 
				
			||||||
# it under the terms of the GNU General Public License as published by
 | 
					# it under the terms of the GNU General Public License as published by
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,7 +3,7 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
# ***** BEGIN LICENSE BLOCK *****
 | 
					# ***** BEGIN LICENSE BLOCK *****
 | 
				
			||||||
# This file is part of InDefero, an open source project management application.
 | 
					# This file is part of InDefero, an open source project management application.
 | 
				
			||||||
# Copyright (C) 2008-2010 Céondo Ltd and contributors.
 | 
					# Copyright (C) 2008-2011 Céondo Ltd and contributors.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# InDefero is free software; you can redistribute it and/or modify
 | 
					# InDefero is free software; you can redistribute it and/or modify
 | 
				
			||||||
# it under the terms of the GNU General Public License as published by
 | 
					# it under the terms of the GNU General Public License as published by
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,7 +3,7 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
# ***** BEGIN LICENSE BLOCK *****
 | 
					# ***** BEGIN LICENSE BLOCK *****
 | 
				
			||||||
# This file is part of InDefero, an open source project management application.
 | 
					# This file is part of InDefero, an open source project management application.
 | 
				
			||||||
# Copyright (C) 2008 Céondo Ltd and contributors.
 | 
					# Copyright (C) 2008-2011 Céondo Ltd and contributors.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# InDefero is free software; you can redistribute it and/or modify
 | 
					# InDefero is free software; you can redistribute it and/or modify
 | 
				
			||||||
# it under the terms of the GNU General Public License as published by
 | 
					# it under the terms of the GNU General Public License as published by
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,7 +3,7 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
# ***** BEGIN LICENSE BLOCK *****
 | 
					# ***** BEGIN LICENSE BLOCK *****
 | 
				
			||||||
# This file is part of InDefero, an open source project management application.
 | 
					# This file is part of InDefero, an open source project management application.
 | 
				
			||||||
# Copyright (C) 2008-2010 Céondo Ltd and contributors.
 | 
					# Copyright (C) 2008-2011 Céondo Ltd and contributors.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# InDefero is free software; you can redistribute it and/or modify
 | 
					# InDefero is free software; you can redistribute it and/or modify
 | 
				
			||||||
# it under the terms of the GNU General Public License as published by
 | 
					# it under the terms of the GNU General Public License as published by
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,7 +3,7 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
# ***** BEGIN LICENSE BLOCK *****
 | 
					# ***** BEGIN LICENSE BLOCK *****
 | 
				
			||||||
# This file is part of InDefero, an open source project management application.
 | 
					# This file is part of InDefero, an open source project management application.
 | 
				
			||||||
# Copyright (C) 2008-2010 Céondo Ltd and contributors.
 | 
					# Copyright (C) 2008-2011 Céondo Ltd and contributors.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# InDefero is free software; you can redistribute it and/or modify
 | 
					# InDefero is free software; you can redistribute it and/or modify
 | 
				
			||||||
# it under the terms of the GNU General Public License as published by
 | 
					# it under the terms of the GNU General Public License as published by
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,7 +3,7 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
# ***** BEGIN LICENSE BLOCK *****
 | 
					# ***** BEGIN LICENSE BLOCK *****
 | 
				
			||||||
# This file is part of InDefero, an open source project management application.
 | 
					# This file is part of InDefero, an open source project management application.
 | 
				
			||||||
# Copyright (C) 2008 Céondo Ltd and contributors.
 | 
					# Copyright (C) 2008-2011 Céondo Ltd and contributors.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# InDefero is free software; you can redistribute it and/or modify
 | 
					# InDefero is free software; you can redistribute it and/or modify
 | 
				
			||||||
# it under the terms of the GNU General Public License as published by
 | 
					# it under the terms of the GNU General Public License as published by
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,7 +3,7 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
# ***** BEGIN LICENSE BLOCK *****
 | 
					# ***** BEGIN LICENSE BLOCK *****
 | 
				
			||||||
# This file is part of InDefero, an open source project management application.
 | 
					# This file is part of InDefero, an open source project management application.
 | 
				
			||||||
# Copyright (C) 2008 Céondo Ltd and contributors.
 | 
					# Copyright (C) 2008-2011 Céondo Ltd and contributors.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# InDefero is free software; you can redistribute it and/or modify
 | 
					# InDefero is free software; you can redistribute it and/or modify
 | 
				
			||||||
# it under the terms of the GNU General Public License as published by
 | 
					# it under the terms of the GNU General Public License as published by
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,7 +3,7 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
# ***** BEGIN LICENSE BLOCK *****
 | 
					# ***** BEGIN LICENSE BLOCK *****
 | 
				
			||||||
# This file is part of InDefero, an open source project management application.
 | 
					# This file is part of InDefero, an open source project management application.
 | 
				
			||||||
# Copyright (C) 2008 Céondo Ltd and contributors.
 | 
					# Copyright (C) 2008-2011 Céondo Ltd and contributors.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# InDefero is free software; you can redistribute it and/or modify
 | 
					# InDefero is free software; you can redistribute it and/or modify
 | 
				
			||||||
# it under the terms of the GNU General Public License as published by
 | 
					# it under the terms of the GNU General Public License as published by
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										209
									
								
								src/IDF/Diff.php
									
									
									
									
									
								
							
							
						
						
									
										209
									
								
								src/IDF/Diff.php
									
									
									
									
									
								
							@@ -3,7 +3,7 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
# ***** BEGIN LICENSE BLOCK *****
 | 
					# ***** BEGIN LICENSE BLOCK *****
 | 
				
			||||||
# This file is part of InDefero, an open source project management application.
 | 
					# This file is part of InDefero, an open source project management application.
 | 
				
			||||||
# Copyright (C) 2008 Céondo Ltd and contributors.
 | 
					# Copyright (C) 2008-2011 Céondo Ltd and contributors.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# InDefero is free software; you can redistribute it and/or modify
 | 
					# InDefero is free software; you can redistribute it and/or modify
 | 
				
			||||||
# it under the terms of the GNU General Public License as published by
 | 
					# it under the terms of the GNU General Public License as published by
 | 
				
			||||||
@@ -27,17 +27,17 @@
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
class IDF_Diff
 | 
					class IDF_Diff
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    public $repo = '';
 | 
					    public $path_strip_level = 0;
 | 
				
			||||||
    public $diff = '';
 | 
					 | 
				
			||||||
    protected $lines = array();
 | 
					    protected $lines = array();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public $files = array();
 | 
					    public $files = array();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function __construct($diff, $repo='')
 | 
					    public function __construct($diff, $path_strip_level = 0)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $this->repo = $repo;
 | 
					        $this->path_strip_level = $path_strip_level;
 | 
				
			||||||
        $this->diff = $diff;
 | 
					        // this works because in unified diff format even empty lines are
 | 
				
			||||||
        $this->lines = preg_split("/\015\012|\015|\012/", $diff);
 | 
					        // either prefixed with a '+', '-' or ' '
 | 
				
			||||||
 | 
					        $this->lines = preg_split("/\015\012|\015|\012/", $diff, -1, PREG_SPLIT_NO_EMPTY);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function parse()
 | 
					    public function parse()
 | 
				
			||||||
@@ -49,118 +49,95 @@ class IDF_Diff
 | 
				
			|||||||
        $files = array();
 | 
					        $files = array();
 | 
				
			||||||
        $indiff = false; // Used to skip the headers in the git patches
 | 
					        $indiff = false; // Used to skip the headers in the git patches
 | 
				
			||||||
        $i = 0; // Used to skip the end of a git patch with --\nversion number
 | 
					        $i = 0; // Used to skip the end of a git patch with --\nversion number
 | 
				
			||||||
        foreach ($this->lines as $line) {
 | 
					        $diffsize = count($this->lines);
 | 
				
			||||||
            $i++;
 | 
					        while ($i < $diffsize) {
 | 
				
			||||||
            if (0 === strpos($line, '--') and isset($this->lines[$i])
 | 
					            // look for the potential beginning of a diff
 | 
				
			||||||
                and preg_match('/^\d+\.\d+\.\d+\.\d+$/', $this->lines[$i])) {
 | 
					            if (substr($this->lines[$i], 0, 4) !== '--- ') {
 | 
				
			||||||
                break;
 | 
					                $i++;
 | 
				
			||||||
 | 
					                continue;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            if (0 === strpos($line, 'diff --git a')) {
 | 
					
 | 
				
			||||||
                $current_file = self::getFile($line);
 | 
					            // we're inside a diff candiate
 | 
				
			||||||
                $files[$current_file] = array();
 | 
					            $oldfileline = $this->lines[$i++];
 | 
				
			||||||
                $files[$current_file]['chunks'] = array();
 | 
					            $newfileline = $this->lines[$i++];
 | 
				
			||||||
                $files[$current_file]['chunks_def'] = array();
 | 
					            if (substr($newfileline, 0, 4) !== '+++ ') {
 | 
				
			||||||
                $current_chunk = 0;
 | 
					                // not a valid diff here, move on
 | 
				
			||||||
                $indiff = true;
 | 
					 | 
				
			||||||
                continue;
 | 
					                continue;
 | 
				
			||||||
            } else if (preg_match('#^diff -r [^\s]+ -r [^\s]+ (.+)$#', $line, $matches)) {
 | 
					            }
 | 
				
			||||||
                $current_file = $matches[1];
 | 
					
 | 
				
			||||||
                $files[$current_file] = array();
 | 
					            // use new file name by default
 | 
				
			||||||
                $files[$current_file]['chunks'] = array();
 | 
					            preg_match("/^\+\+\+ ([^\t]+)/", $newfileline, $m);
 | 
				
			||||||
                $files[$current_file]['chunks_def'] = array();
 | 
					            $current_file = $m[1];
 | 
				
			||||||
                $current_chunk = 0;
 | 
					            if ($current_file === '/dev/null') {
 | 
				
			||||||
                $indiff = true;
 | 
					                // except if it's /dev/null, use the old one instead
 | 
				
			||||||
                continue;
 | 
					                // eg. mtn 0.48 and newer
 | 
				
			||||||
            } else if (!$indiff && 0 === strpos($line, '=========')) {
 | 
					                preg_match("/^--- ([^\t]+)/", $oldfileline, $m);
 | 
				
			||||||
                // ignore pseudo stanzas with a hint of a binary file
 | 
					                $current_file = $m[1];
 | 
				
			||||||
                if (preg_match("/^# (.+) is binary/", $this->lines[$i]))
 | 
					            }
 | 
				
			||||||
                    continue;
 | 
					            if ($this->path_strip_level > 0) {
 | 
				
			||||||
                // by default always use the new name of a possibly renamed file
 | 
					                $fileparts = explode('/', $current_file, $this->path_strip_level+1);
 | 
				
			||||||
                $current_file = self::getMtnFile($this->lines[$i+1]);
 | 
					                $current_file = array_pop($fileparts);
 | 
				
			||||||
                // mtn 0.48 and newer set /dev/null as file path for dropped files
 | 
					            }
 | 
				
			||||||
                // so we display the old name here
 | 
					            $current_chunk = 0;
 | 
				
			||||||
                if ($current_file == "/dev/null") {
 | 
					            $files[$current_file] = array();
 | 
				
			||||||
                    $current_file = self::getMtnFile($this->lines[$i]);
 | 
					            $files[$current_file]['chunks'] = array();
 | 
				
			||||||
 | 
					            $files[$current_file]['chunks_def'] = array();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            while ($i < $diffsize && substr($this->lines[$i], 0, 3) === '@@ ') {
 | 
				
			||||||
 | 
					                $elems = preg_match('/@@ -(\d+),?(\d*) \+(\d+),?(\d*) @@.*/',
 | 
				
			||||||
 | 
					                                    $this->lines[$i++], $results);
 | 
				
			||||||
 | 
					                if ($elems != 1) {
 | 
				
			||||||
 | 
					                    // hunk is badly formatted
 | 
				
			||||||
 | 
					                    break;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                if ($current_file == "/dev/null") {
 | 
					                $delstart = $results[1];
 | 
				
			||||||
                    throw new Exception(
 | 
					                $dellines = $results[2] === '' ? 1 : $results[2];
 | 
				
			||||||
                        "could not determine path from diff"
 | 
					                $addstart = $results[3];
 | 
				
			||||||
                    );
 | 
					                $addlines = $results[4] === '' ? 1 : $results[4];
 | 
				
			||||||
                }
 | 
					
 | 
				
			||||||
                $files[$current_file] = array();
 | 
					                $files[$current_file]['chunks_def'][] = array(
 | 
				
			||||||
                $files[$current_file]['chunks'] = array();
 | 
					                    array($delstart, $dellines), array($addstart, $addlines)
 | 
				
			||||||
                $files[$current_file]['chunks_def'] = array();
 | 
					                );
 | 
				
			||||||
                $current_chunk = 0;
 | 
					 | 
				
			||||||
                $indiff = true;
 | 
					 | 
				
			||||||
                continue;
 | 
					 | 
				
			||||||
            } else if (0 === strpos($line, 'Index: ')) {
 | 
					 | 
				
			||||||
                $current_file = self::getSvnFile($line);
 | 
					 | 
				
			||||||
                $files[$current_file] = array();
 | 
					 | 
				
			||||||
                $files[$current_file]['chunks'] = array();
 | 
					 | 
				
			||||||
                $files[$current_file]['chunks_def'] = array();
 | 
					 | 
				
			||||||
                $current_chunk = 0;
 | 
					 | 
				
			||||||
                $indiff = true;
 | 
					 | 
				
			||||||
                continue;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            if (!$indiff) {
 | 
					 | 
				
			||||||
                continue;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            if (0 === strpos($line, '@@ ')) {
 | 
					 | 
				
			||||||
                $files[$current_file]['chunks_def'][] = self::getChunk($line);
 | 
					 | 
				
			||||||
                $files[$current_file]['chunks'][] = array();
 | 
					                $files[$current_file]['chunks'][] = array();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                while ($i < $diffsize && ($addlines >= 0 || $dellines >= 0)) {
 | 
				
			||||||
 | 
					                    $linetype = $this->lines[$i] != '' ? $this->lines[$i][0] : false;
 | 
				
			||||||
 | 
					                    switch ($linetype) {
 | 
				
			||||||
 | 
					                        case ' ':
 | 
				
			||||||
 | 
					                            $files[$current_file]['chunks'][$current_chunk][] =
 | 
				
			||||||
 | 
					                                array($delstart, $addstart, substr($this->lines[$i++], 1));
 | 
				
			||||||
 | 
					                            $dellines--;
 | 
				
			||||||
 | 
					                            $addlines--;
 | 
				
			||||||
 | 
					                            $delstart++;
 | 
				
			||||||
 | 
					                            $addstart++;
 | 
				
			||||||
 | 
					                            break;
 | 
				
			||||||
 | 
					                        case '+':
 | 
				
			||||||
 | 
					                            $files[$current_file]['chunks'][$current_chunk][] =
 | 
				
			||||||
 | 
					                                array('', $addstart, substr($this->lines[$i++], 1));
 | 
				
			||||||
 | 
					                            $addlines--;
 | 
				
			||||||
 | 
					                            $addstart++;
 | 
				
			||||||
 | 
					                            break;
 | 
				
			||||||
 | 
					                        case '-':
 | 
				
			||||||
 | 
					                            $files[$current_file]['chunks'][$current_chunk][] =
 | 
				
			||||||
 | 
					                                array($delstart, '', substr($this->lines[$i++], 1));
 | 
				
			||||||
 | 
					                            $dellines--;
 | 
				
			||||||
 | 
					                            $delstart++;
 | 
				
			||||||
 | 
					                            break;
 | 
				
			||||||
 | 
					                        case '\\':
 | 
				
			||||||
 | 
					                            // ignore newline handling for now, see issue 636
 | 
				
			||||||
 | 
					                            $i++;
 | 
				
			||||||
 | 
					                            continue;
 | 
				
			||||||
 | 
					                        default:
 | 
				
			||||||
 | 
					                            break 2;
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
                $current_chunk++;
 | 
					                $current_chunk++;
 | 
				
			||||||
                $lline = $files[$current_file]['chunks_def'][$current_chunk-1][0][0];
 | 
					 | 
				
			||||||
                $rline = $files[$current_file]['chunks_def'][$current_chunk-1][1][0];
 | 
					 | 
				
			||||||
                continue;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            if (0 === strpos($line, '---') or 0 === strpos($line, '+++')) {
 | 
					 | 
				
			||||||
                continue;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            if (0 === strpos($line, '-')) {
 | 
					 | 
				
			||||||
                $files[$current_file]['chunks'][$current_chunk-1][] = array($lline, '', substr($line, 1));
 | 
					 | 
				
			||||||
                $lline++;
 | 
					 | 
				
			||||||
                continue;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            if (0 === strpos($line, '+')) {
 | 
					 | 
				
			||||||
                $files[$current_file]['chunks'][$current_chunk-1][] = array('', $rline, substr($line, 1));
 | 
					 | 
				
			||||||
                $rline++;
 | 
					 | 
				
			||||||
                continue;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            if (0 === strpos($line, ' ')) {
 | 
					 | 
				
			||||||
                $files[$current_file]['chunks'][$current_chunk-1][] = array($lline, $rline, substr($line, 1));
 | 
					 | 
				
			||||||
                $rline++;
 | 
					 | 
				
			||||||
                $lline++;
 | 
					 | 
				
			||||||
                continue;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            if ($line == '') {
 | 
					 | 
				
			||||||
                $files[$current_file]['chunks'][$current_chunk-1][] = array($lline, $rline, $line);
 | 
					 | 
				
			||||||
                $rline++;
 | 
					 | 
				
			||||||
                $lline++;
 | 
					 | 
				
			||||||
                continue;
 | 
					 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        $this->files = $files;
 | 
					        $this->files = $files;
 | 
				
			||||||
        return $files;
 | 
					        return $files;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public static function getFile($line)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $line = substr(trim($line), 10);
 | 
					 | 
				
			||||||
        $n = (int) strlen($line)/2;
 | 
					 | 
				
			||||||
        return trim(substr($line, 3, $n-3));
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public static function getSvnFile($line)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        return substr(trim($line), 7);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public static function getMtnFile($line)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        preg_match("/^[+-]{3} ([^\t]+)/", $line, $m);
 | 
					 | 
				
			||||||
        return $m[1];
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Return the html version of a parsed diff.
 | 
					     * Return the html version of a parsed diff.
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
@@ -197,7 +174,6 @@ class IDF_Diff
 | 
				
			|||||||
        return Pluf_Template::markSafe($out);
 | 
					        return Pluf_Template::markSafe($out);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
    public static function padLine($line)
 | 
					    public static function padLine($line)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $line = str_replace("\t", '    ', $line);
 | 
					        $line = str_replace("\t", '    ', $line);
 | 
				
			||||||
@@ -210,19 +186,6 @@ class IDF_Diff
 | 
				
			|||||||
        return str_repeat(' ', $i).substr($line, $i);
 | 
					        return str_repeat(' ', $i).substr($line, $i);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * @return array array(array(start, n), array(start, n))
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    public static function getChunk($line)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $elts = explode(' ', $line);
 | 
					 | 
				
			||||||
        $res = array();
 | 
					 | 
				
			||||||
        for ($i=1;$i<3;$i++) {
 | 
					 | 
				
			||||||
            $res[] = explode(',', trim(substr($elts[$i], 1)));
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        return $res;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Review patch.
 | 
					     * Review patch.
 | 
				
			||||||
     *
 | 
					     *
 | 
				
			||||||
@@ -347,7 +310,6 @@ class IDF_Diff
 | 
				
			|||||||
        return $nnew_chunks;
 | 
					        return $nnew_chunks;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function renderCompared($chunks, $filename)
 | 
					    public function renderCompared($chunks, $filename)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $fileinfo = IDF_FileUtil::getMimeType($filename);
 | 
					        $fileinfo = IDF_FileUtil::getMimeType($filename);
 | 
				
			||||||
@@ -381,6 +343,5 @@ class IDF_Diff
 | 
				
			|||||||
            $i++;
 | 
					            $i++;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        return Pluf_Template::markSafe($out);
 | 
					        return Pluf_Template::markSafe($out);
 | 
				
			||||||
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										96
									
								
								src/IDF/EmailAddress.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										96
									
								
								src/IDF/EmailAddress.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,96 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					/* -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					# ***** BEGIN LICENSE BLOCK *****
 | 
				
			||||||
 | 
					# This file is part of InDefero, an open source project management application.
 | 
				
			||||||
 | 
					# Copyright (C) 2008-2011 Céondo Ltd and contributors.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# InDefero is free software; you can redistribute it and/or modify
 | 
				
			||||||
 | 
					# it under the terms of the GNU General Public License as published by
 | 
				
			||||||
 | 
					# the Free Software Foundation; either version 2 of the License, or
 | 
				
			||||||
 | 
					# (at your option) any later version.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# InDefero is distributed in the hope that it will be useful,
 | 
				
			||||||
 | 
					# but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
				
			||||||
 | 
					# GNU General Public License for more details.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# You should have received a copy of the GNU General Public License
 | 
				
			||||||
 | 
					# along with this program; if not, write to the Free Software
 | 
				
			||||||
 | 
					# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# ***** END LICENSE BLOCK ***** */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Storage of Email addresses
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					class IDF_EmailAddress extends Pluf_Model
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public $_model = __CLASS__;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    function init()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $this->_a['table'] = 'idf_emailaddresses';
 | 
				
			||||||
 | 
					        $this->_a['model'] = __CLASS__;
 | 
				
			||||||
 | 
					        $this->_a['cols'] = array(
 | 
				
			||||||
 | 
					                             // It is mandatory to have an "id" column.
 | 
				
			||||||
 | 
					                            'id' =>
 | 
				
			||||||
 | 
					                            array(
 | 
				
			||||||
 | 
					                                  'type' => 'Pluf_DB_Field_Sequence',
 | 
				
			||||||
 | 
					                                  //It is automatically added.
 | 
				
			||||||
 | 
					                                  'blank' => true,
 | 
				
			||||||
 | 
					                                  ),
 | 
				
			||||||
 | 
					                            'user' =>
 | 
				
			||||||
 | 
					                            array(
 | 
				
			||||||
 | 
					                                  'type' => 'Pluf_DB_Field_Foreignkey',
 | 
				
			||||||
 | 
					                                  'model' => 'Pluf_User',
 | 
				
			||||||
 | 
					                                  'blank' => false,
 | 
				
			||||||
 | 
					                                  'verbose' => __('user'),
 | 
				
			||||||
 | 
					                                  ),
 | 
				
			||||||
 | 
					                            'address' =>
 | 
				
			||||||
 | 
					                            array(
 | 
				
			||||||
 | 
					                                  'type' => 'Pluf_DB_Field_Email',
 | 
				
			||||||
 | 
					                                  'blank' => false,
 | 
				
			||||||
 | 
					                                  'verbose' => __('email'),
 | 
				
			||||||
 | 
					                                  'unique' => true,
 | 
				
			||||||
 | 
					                                  ),
 | 
				
			||||||
 | 
					                            );
 | 
				
			||||||
 | 
					        // WARNING: Not using getSqlTable on the Pluf_User object to
 | 
				
			||||||
 | 
					        // avoid recursion.
 | 
				
			||||||
 | 
					        $t_users = $this->_con->pfx.'users';
 | 
				
			||||||
 | 
					        $this->_a['views'] = array(
 | 
				
			||||||
 | 
					                              'join_user' =>
 | 
				
			||||||
 | 
					                              array(
 | 
				
			||||||
 | 
					                                    'join' => 'LEFT JOIN '.$t_users
 | 
				
			||||||
 | 
					                                    .' ON '.$t_users.'.id='.$this->_con->qn('user'),
 | 
				
			||||||
 | 
					                                    'select' => $this->getSelect().', '
 | 
				
			||||||
 | 
					                                    .$t_users.'.login AS login',
 | 
				
			||||||
 | 
					                                    'props' => array('login' => 'login'),
 | 
				
			||||||
 | 
					                                    )
 | 
				
			||||||
 | 
					                                   );
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    function get_email_addresses_for_user($user)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $addr = $user->get_idf_emailaddress_list();
 | 
				
			||||||
 | 
					        $addr[] = (object)array("address" => $user->email, "id" => -1, "user" => $user);
 | 
				
			||||||
 | 
					        return $addr;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    function get_user_for_email_address($email)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $sql = new Pluf_SQL('email=%s', array($email));
 | 
				
			||||||
 | 
					        $users = Pluf::factory('Pluf_User')->getList(array('filter'=>$sql->gen()));
 | 
				
			||||||
 | 
					        if ($users->count() > 0) {
 | 
				
			||||||
 | 
					            return $users[0];
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        $sql = new Pluf_SQL('address=%s', array($email));
 | 
				
			||||||
 | 
					        $matches = Pluf::factory('IDF_EmailAddress')->getList(array('filter'=>$sql->gen()));
 | 
				
			||||||
 | 
					        if ($matches->count() > 0) {
 | 
				
			||||||
 | 
					            return new Pluf_User($matches[0]->user);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return null;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -3,7 +3,7 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
# ***** BEGIN LICENSE BLOCK *****
 | 
					# ***** BEGIN LICENSE BLOCK *****
 | 
				
			||||||
# This file is part of InDefero, an open source project management application.
 | 
					# This file is part of InDefero, an open source project management application.
 | 
				
			||||||
# Copyright (C) 2010 Céondo Ltd and contributors.
 | 
					# Copyright (C) 2008-2011 Céondo Ltd and contributors.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# InDefero is free software; you can redistribute it and/or modify
 | 
					# InDefero is free software; you can redistribute it and/or modify
 | 
				
			||||||
# it under the terms of the GNU General Public License as published by
 | 
					# it under the terms of the GNU General Public License as published by
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,7 +3,7 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
# ***** BEGIN LICENSE BLOCK *****
 | 
					# ***** BEGIN LICENSE BLOCK *****
 | 
				
			||||||
# This file is part of InDefero, an open source project management application.
 | 
					# This file is part of InDefero, an open source project management application.
 | 
				
			||||||
# Copyright (C) 2008 Céondo Ltd and contributors.
 | 
					# Copyright (C) 2008-2011 Céondo Ltd and contributors.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# InDefero is free software; you can redistribute it and/or modify
 | 
					# InDefero is free software; you can redistribute it and/or modify
 | 
				
			||||||
# it under the terms of the GNU General Public License as published by
 | 
					# it under the terms of the GNU General Public License as published by
 | 
				
			||||||
@@ -182,7 +182,7 @@ class IDF_Form_Admin_ProjectCreate extends Pluf_Form
 | 
				
			|||||||
        // we accept only starting with http(s):// to avoid people
 | 
					        // we accept only starting with http(s):// to avoid people
 | 
				
			||||||
        // trying to access the local filesystem.
 | 
					        // trying to access the local filesystem.
 | 
				
			||||||
        if (!preg_match('#^(http|https)://#', $url)) {
 | 
					        if (!preg_match('#^(http|https)://#', $url)) {
 | 
				
			||||||
            throw new Pluf_Form_Invalid(__('Only a remote repository available throught http or https are allowed. For example "http://somewhere.com/svn/trunk".'));
 | 
					            throw new Pluf_Form_Invalid(__('Only a remote repository available through HTTP or HTTPS is allowed. For example "http://somewhere.com/svn/trunk".'));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        return $url;
 | 
					        return $url;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -319,6 +319,7 @@ class IDF_Form_Admin_ProjectCreate extends Pluf_Form
 | 
				
			|||||||
                           'labels_issue_closed' => IDF_Form_IssueTrackingConf::init_closed,
 | 
					                           'labels_issue_closed' => IDF_Form_IssueTrackingConf::init_closed,
 | 
				
			||||||
                           'labels_issue_predefined' =>  IDF_Form_IssueTrackingConf::init_predefined,
 | 
					                           'labels_issue_predefined' =>  IDF_Form_IssueTrackingConf::init_predefined,
 | 
				
			||||||
                           'labels_issue_one_max' => IDF_Form_IssueTrackingConf::init_one_max,
 | 
					                           'labels_issue_one_max' => IDF_Form_IssueTrackingConf::init_one_max,
 | 
				
			||||||
 | 
					                           'issue_relations' => IDF_Form_IssueTrackingConf::init_relations,
 | 
				
			||||||
                           'webhook_url' => '',
 | 
					                           'webhook_url' => '',
 | 
				
			||||||
                           'downloads_access_rights' => 'all',
 | 
					                           'downloads_access_rights' => 'all',
 | 
				
			||||||
                           'review_access_rights' => 'all',
 | 
					                           'review_access_rights' => 'all',
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,7 +3,7 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
# ***** BEGIN LICENSE BLOCK *****
 | 
					# ***** BEGIN LICENSE BLOCK *****
 | 
				
			||||||
# This file is part of InDefero, an open source project management application.
 | 
					# This file is part of InDefero, an open source project management application.
 | 
				
			||||||
# Copyright (C) 2008 Céondo Ltd and contributors.
 | 
					# Copyright (C) 2008-2011 Céondo Ltd and contributors.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# InDefero is free software; you can redistribute it and/or modify
 | 
					# InDefero is free software; you can redistribute it and/or modify
 | 
				
			||||||
# it under the terms of the GNU General Public License as published by
 | 
					# it under the terms of the GNU General Public License as published by
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,7 +3,7 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
# ***** BEGIN LICENSE BLOCK *****
 | 
					# ***** BEGIN LICENSE BLOCK *****
 | 
				
			||||||
# This file is part of InDefero, an open source project management application.
 | 
					# This file is part of InDefero, an open source project management application.
 | 
				
			||||||
# Copyright (C) 2008 Céondo Ltd and contributors.
 | 
					# Copyright (C) 2008-2011 Céondo Ltd and contributors.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# InDefero is free software; you can redistribute it and/or modify
 | 
					# InDefero is free software; you can redistribute it and/or modify
 | 
				
			||||||
# it under the terms of the GNU General Public License as published by
 | 
					# it under the terms of the GNU General Public License as published by
 | 
				
			||||||
@@ -88,7 +88,7 @@ class IDF_Form_Admin_ProjectUpdate extends Pluf_Form
 | 
				
			|||||||
                        $mtn_master_branch)) {
 | 
					                        $mtn_master_branch)) {
 | 
				
			||||||
            throw new Pluf_Form_Invalid(__(
 | 
					            throw new Pluf_Form_Invalid(__(
 | 
				
			||||||
                'The master branch is empty or contains illegal characters, '.
 | 
					                'The master branch is empty or contains illegal characters, '.
 | 
				
			||||||
                'please use only letters, digits, dashs and dots as separators.'
 | 
					                'please use only letters, digits, dashes and dots as separators.'
 | 
				
			||||||
            ));
 | 
					            ));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,7 +3,7 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
# ***** BEGIN LICENSE BLOCK *****
 | 
					# ***** BEGIN LICENSE BLOCK *****
 | 
				
			||||||
# This file is part of InDefero, an open source project management application.
 | 
					# This file is part of InDefero, an open source project management application.
 | 
				
			||||||
# Copyright (C) 2008 Céondo Ltd and contributors.
 | 
					# Copyright (C) 2008-2011 Céondo Ltd and contributors.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# InDefero is free software; you can redistribute it and/or modify
 | 
					# InDefero is free software; you can redistribute it and/or modify
 | 
				
			||||||
# it under the terms of the GNU General Public License as published by
 | 
					# it under the terms of the GNU General Public License as published by
 | 
				
			||||||
@@ -68,7 +68,7 @@ class IDF_Form_Admin_UserCreate extends Pluf_Form
 | 
				
			|||||||
                                      array('required' => true,
 | 
					                                      array('required' => true,
 | 
				
			||||||
                                            'label' => __('Email'),
 | 
					                                            'label' => __('Email'),
 | 
				
			||||||
                                            'initial' => '',
 | 
					                                            'initial' => '',
 | 
				
			||||||
                                            'help_text' => __('Double check the email address as the password is directly sent to the user.'),
 | 
					                                            'help_text' => __('Double check the email address as the password is sent directly to the user.'),
 | 
				
			||||||
                                            ));
 | 
					                                            ));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $this->fields['language'] = new Pluf_Form_Field_Varchar(
 | 
					        $this->fields['language'] = new Pluf_Form_Field_Varchar(
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,7 +3,7 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
# ***** BEGIN LICENSE BLOCK *****
 | 
					# ***** BEGIN LICENSE BLOCK *****
 | 
				
			||||||
# This file is part of InDefero, an open source project management application.
 | 
					# This file is part of InDefero, an open source project management application.
 | 
				
			||||||
# Copyright (C) 2008 Céondo Ltd and contributors.
 | 
					# Copyright (C) 2008-2011 Céondo Ltd and contributors.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# InDefero is free software; you can redistribute it and/or modify
 | 
					# InDefero is free software; you can redistribute it and/or modify
 | 
				
			||||||
# it under the terms of the GNU General Public License as published by
 | 
					# it under the terms of the GNU General Public License as published by
 | 
				
			||||||
@@ -78,7 +78,7 @@ class IDF_Form_Admin_UserUpdate extends Pluf_Form
 | 
				
			|||||||
                                            'label' => __('Password'),
 | 
					                                            'label' => __('Password'),
 | 
				
			||||||
                                            'initial' => '',
 | 
					                                            'initial' => '',
 | 
				
			||||||
                                            'widget' => 'Pluf_Form_Widget_PasswordInput',
 | 
					                                            'widget' => 'Pluf_Form_Widget_PasswordInput',
 | 
				
			||||||
                                            'help_text' => Pluf_Template::markSafe(__('Leave blank if you do not want to change the password.').'<br />'.__('The password must be hard for other people to find it, but easy for the user to remember.')),
 | 
					                                            'help_text' => Pluf_Template::markSafe(__('Leave blank if you do not want to change the password.').'<br />'.__('The password must be hard for other people to guess, but easy for the user to remember.')),
 | 
				
			||||||
                                            'widget_attrs' => array(
 | 
					                                            'widget_attrs' => array(
 | 
				
			||||||
                                                       'maxlength' => 50,
 | 
					                                                       'maxlength' => 50,
 | 
				
			||||||
                                                       'size' => 15,
 | 
					                                                       'size' => 15,
 | 
				
			||||||
@@ -161,7 +161,7 @@ class IDF_Form_Admin_UserUpdate extends Pluf_Form
 | 
				
			|||||||
                          'label' => __('Staff'),
 | 
					                          'label' => __('Staff'),
 | 
				
			||||||
                          'initial' => $this->user->staff,
 | 
					                          'initial' => $this->user->staff,
 | 
				
			||||||
                          'widget' => 'Pluf_Form_Widget_CheckboxInput',
 | 
					                          'widget' => 'Pluf_Form_Widget_CheckboxInput',
 | 
				
			||||||
                          'help_text' => __('If you give staff rights to a user, you really need to trust him.'),
 | 
					                          'help_text' => __('If you give staff rights to a user, you really need to trust them.'),
 | 
				
			||||||
                          ));
 | 
					                          ));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -173,7 +173,7 @@ class IDF_Form_Admin_UserUpdate extends Pluf_Form
 | 
				
			|||||||
                          'initial' => $this->user->active,
 | 
					                          'initial' => $this->user->active,
 | 
				
			||||||
                          'widget' => 'Pluf_Form_Widget_CheckboxInput',
 | 
					                          'widget' => 'Pluf_Form_Widget_CheckboxInput',
 | 
				
			||||||
                          'widget_attrs' => $attrs,
 | 
					                          'widget_attrs' => $attrs,
 | 
				
			||||||
                          'help_text' => __('If the user is not getting the confirmation email or is abusing the system, you can directly enable or disable his account here.'),
 | 
					                          'help_text' => __('If the user is not getting the confirmation email or is abusing the system, you can directly enable or disable their account here.'),
 | 
				
			||||||
                          ));
 | 
					                          ));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,19 +3,19 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
# ***** BEGIN LICENSE BLOCK *****
 | 
					# ***** BEGIN LICENSE BLOCK *****
 | 
				
			||||||
# This file is part of InDefero, an open source project management application.
 | 
					# This file is part of InDefero, an open source project management application.
 | 
				
			||||||
# Copyright (C) 2010 Céondo Ltd and contributors.
 | 
					# Copyright (C) 2008-2011 Céondo Ltd and contributors.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# Plume Framework is free software; you can redistribute it and/or modify
 | 
					# InDefero is free software; you can redistribute it and/or modify
 | 
				
			||||||
# it under the terms of the GNU Lesser General Public License as published by
 | 
					# it under the terms of the GNU General Public License as published by
 | 
				
			||||||
# the Free Software Foundation; either version 2.1 of the License, or
 | 
					# the Free Software Foundation; either version 2 of the License, or
 | 
				
			||||||
# (at your option) any later version.
 | 
					# (at your option) any later version.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# Plume Framework is distributed in the hope that it will be useful,
 | 
					# InDefero is distributed in the hope that it will be useful,
 | 
				
			||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
					# but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
					# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
				
			||||||
# GNU Lesser General Public License for more details.
 | 
					# GNU General Public License for more details.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# You should have received a copy of the GNU Lesser General Public License
 | 
					# You should have received a copy of the GNU General Public License
 | 
				
			||||||
# along with this program; if not, write to the Free Software
 | 
					# along with this program; if not, write to the Free Software
 | 
				
			||||||
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 | 
					# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,7 +3,7 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
# ***** BEGIN LICENSE BLOCK *****
 | 
					# ***** BEGIN LICENSE BLOCK *****
 | 
				
			||||||
# This file is part of InDefero, an open source project management application.
 | 
					# This file is part of InDefero, an open source project management application.
 | 
				
			||||||
# Copyright (C) 2008 Céondo Ltd and contributors.
 | 
					# Copyright (C) 2008-2011 Céondo Ltd and contributors.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# InDefero is free software; you can redistribute it and/or modify
 | 
					# InDefero is free software; you can redistribute it and/or modify
 | 
				
			||||||
# it under the terms of the GNU General Public License as published by
 | 
					# it under the terms of the GNU General Public License as published by
 | 
				
			||||||
@@ -36,6 +36,7 @@ class IDF_Form_IssueCreate extends Pluf_Form
 | 
				
			|||||||
    public $user = null;
 | 
					    public $user = null;
 | 
				
			||||||
    public $project = null;
 | 
					    public $project = null;
 | 
				
			||||||
    public $show_full = false;
 | 
					    public $show_full = false;
 | 
				
			||||||
 | 
					    public $relation_types = null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function initFields($extra=array())
 | 
					    public function initFields($extra=array())
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
@@ -45,9 +46,12 @@ class IDF_Form_IssueCreate extends Pluf_Form
 | 
				
			|||||||
            or $this->user->hasPerm('IDF.project-member', $this->project)) {
 | 
					            or $this->user->hasPerm('IDF.project-member', $this->project)) {
 | 
				
			||||||
            $this->show_full = true;
 | 
					            $this->show_full = true;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					        $this->relation_types = $this->project->getRelationsFromConfig();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $contentTemplate = $this->project->getConf()->getVal(
 | 
					        $contentTemplate = $this->project->getConf()->getVal(
 | 
				
			||||||
            'labels_issue_template', IDF_Form_IssueTrackingConf::init_template
 | 
					            'labels_issue_template', IDF_Form_IssueTrackingConf::init_template
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $this->fields['summary'] = new Pluf_Form_Field_Varchar(
 | 
					        $this->fields['summary'] = new Pluf_Form_Field_Varchar(
 | 
				
			||||||
                                      array('required' => true,
 | 
					                                      array('required' => true,
 | 
				
			||||||
                                            'label' => __('Summary'),
 | 
					                                            'label' => __('Summary'),
 | 
				
			||||||
@@ -76,11 +80,11 @@ class IDF_Form_IssueCreate extends Pluf_Form
 | 
				
			|||||||
        // case of someone allowing the upload path to be accessible
 | 
					        // case of someone allowing the upload path to be accessible
 | 
				
			||||||
        // to everybody.
 | 
					        // to everybody.
 | 
				
			||||||
        for ($i=1;$i<4;$i++) {
 | 
					        for ($i=1;$i<4;$i++) {
 | 
				
			||||||
            $filename = substr($md5, 0, 2).'/'.substr($md5, 2, 2).'/'.substr($md5, 4).'/%s.dummy'; 
 | 
					            $filename = substr($md5, 0, 2).'/'.substr($md5, 2, 2).'/'.substr($md5, 4).'/%s.dummy';
 | 
				
			||||||
            $this->fields['attachment'.$i] = new Pluf_Form_Field_File(
 | 
					            $this->fields['attachment'.$i] = new Pluf_Form_Field_File(
 | 
				
			||||||
                array('required' => false,
 | 
					                array('required' => false,
 | 
				
			||||||
                      'label' => __('Attach a file'),
 | 
					                      'label' => __('Attach a file'),
 | 
				
			||||||
                      'move_function_params' => 
 | 
					                      'move_function_params' =>
 | 
				
			||||||
                      array('upload_path' => $upload_path,
 | 
					                      array('upload_path' => $upload_path,
 | 
				
			||||||
                            'upload_path_create' => true,
 | 
					                            'upload_path_create' => true,
 | 
				
			||||||
                            'file_name' => $filename,
 | 
					                            'file_name' => $filename,
 | 
				
			||||||
@@ -109,6 +113,20 @@ class IDF_Form_IssueCreate extends Pluf_Form
 | 
				
			|||||||
                                                                    ),
 | 
					                                                                    ),
 | 
				
			||||||
                                            ));
 | 
					                                            ));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $this->fields['relation_type0'] = new Pluf_Form_Field_Varchar(
 | 
				
			||||||
 | 
					                          array('required' => false,
 | 
				
			||||||
 | 
					                                'label' => __('This issue'),
 | 
				
			||||||
 | 
					                                'initial' => current($this->relation_types),
 | 
				
			||||||
 | 
					                                'widget_attrs' => array('size' => 15),
 | 
				
			||||||
 | 
					                                ));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $this->fields['relation_issue0'] = new Pluf_Form_Field_Varchar(
 | 
				
			||||||
 | 
					                          array('required' => false,
 | 
				
			||||||
 | 
					                                'label' => null,
 | 
				
			||||||
 | 
					                                'initial' => '',
 | 
				
			||||||
 | 
					                                'widget_attrs' => array('size' => 10),
 | 
				
			||||||
 | 
					                                ));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            /*
 | 
					            /*
 | 
				
			||||||
             * get predefined tags for issues from current project
 | 
					             * get predefined tags for issues from current project
 | 
				
			||||||
             *
 | 
					             *
 | 
				
			||||||
@@ -181,7 +199,7 @@ class IDF_Form_IssueCreate extends Pluf_Form
 | 
				
			|||||||
            $this->cleaned_data['label'.$i] = trim($this->cleaned_data['label'.$i]);
 | 
					            $this->cleaned_data['label'.$i] = trim($this->cleaned_data['label'.$i]);
 | 
				
			||||||
            if (strpos($this->cleaned_data['label'.$i], ':') !== false) {
 | 
					            if (strpos($this->cleaned_data['label'.$i], ':') !== false) {
 | 
				
			||||||
                list($class, $name) = explode(':', $this->cleaned_data['label'.$i], 2);
 | 
					                list($class, $name) = explode(':', $this->cleaned_data['label'.$i], 2);
 | 
				
			||||||
                list($class, $name) = array(mb_strtolower(trim($class)), 
 | 
					                list($class, $name) = array(mb_strtolower(trim($class)),
 | 
				
			||||||
                                            trim($name));
 | 
					                                            trim($name));
 | 
				
			||||||
            } else {
 | 
					            } else {
 | 
				
			||||||
                $class = 'other';
 | 
					                $class = 'other';
 | 
				
			||||||
@@ -215,10 +233,10 @@ class IDF_Form_IssueCreate extends Pluf_Form
 | 
				
			|||||||
    function clean_status()
 | 
					    function clean_status()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        // Check that the status is in the list of official status
 | 
					        // Check that the status is in the list of official status
 | 
				
			||||||
        $tags = $this->project->getTagsFromConfig('labels_issue_open', 
 | 
					        $tags = $this->project->getTagsFromConfig('labels_issue_open',
 | 
				
			||||||
                                          IDF_Form_IssueTrackingConf::init_open,
 | 
					                                          IDF_Form_IssueTrackingConf::init_open,
 | 
				
			||||||
                                          'Status');
 | 
					                                          'Status');
 | 
				
			||||||
        $tags = array_merge($this->project->getTagsFromConfig('labels_issue_closed', 
 | 
					        $tags = array_merge($this->project->getTagsFromConfig('labels_issue_closed',
 | 
				
			||||||
                                          IDF_Form_IssueTrackingConf::init_closed,
 | 
					                                          IDF_Form_IssueTrackingConf::init_closed,
 | 
				
			||||||
                                          'Status')
 | 
					                                          'Status')
 | 
				
			||||||
                            , $tags);
 | 
					                            , $tags);
 | 
				
			||||||
@@ -235,6 +253,63 @@ class IDF_Form_IssueCreate extends Pluf_Form
 | 
				
			|||||||
        return $this->cleaned_data['status'];
 | 
					        return $this->cleaned_data['status'];
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // this method is not called from Pluf_Form directly, but shared for
 | 
				
			||||||
 | 
					    // among all similar fields
 | 
				
			||||||
 | 
					    function clean_relation_type($value)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $relation_type = trim($value);
 | 
				
			||||||
 | 
					        if (empty($relation_type))
 | 
				
			||||||
 | 
					            return '';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $found = false;
 | 
				
			||||||
 | 
					        foreach ($this->relation_types as $type) {
 | 
				
			||||||
 | 
					            if ($type == $relation_type) {
 | 
				
			||||||
 | 
					                $found = true;
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if (!$found) {
 | 
				
			||||||
 | 
					            throw new Pluf_Form_Invalid(__('You provided an invalid relation type.'));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return $relation_type;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    function clean_relation_type0()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return $this->clean_relation_type($this->cleaned_data['relation_type0']);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // this method is not called from Pluf_Form directly, but shared for
 | 
				
			||||||
 | 
					    // among all similar fields
 | 
				
			||||||
 | 
					    function clean_relation_issue($value)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $issues = trim($value);
 | 
				
			||||||
 | 
					        if (empty($issues))
 | 
				
			||||||
 | 
					            return '';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $issue_ids = preg_split('/\s*,\s*/', $issues, -1, PREG_SPLIT_NO_EMPTY);
 | 
				
			||||||
 | 
					        foreach ($issue_ids as $issue_id) {
 | 
				
			||||||
 | 
					            if (!ctype_digit($issue_id) || (int)$issue_id < 1) {
 | 
				
			||||||
 | 
					                throw new Pluf_Form_Invalid(sprintf(
 | 
				
			||||||
 | 
					                    __('The value "%s" is not a valid issue id.'), $issue_id
 | 
				
			||||||
 | 
					                ));
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            $issue = new IDF_Issue($issue_id);
 | 
				
			||||||
 | 
					            if ($issue->id != $issue_id || $issue->project != $this->project->id) {
 | 
				
			||||||
 | 
					                throw new Pluf_Form_Invalid(sprintf(
 | 
				
			||||||
 | 
					                    __('The issue "%s" does not exist.'), $issue_id
 | 
				
			||||||
 | 
					                ));
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return implode(', ', $issue_ids);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    function clean_relation_issue0()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return $this->clean_relation_issue($this->cleaned_data['relation_issue0']);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Clean the attachments post failure.
 | 
					     * Clean the attachments post failure.
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
@@ -298,6 +373,30 @@ class IDF_Form_IssueCreate extends Pluf_Form
 | 
				
			|||||||
        foreach ($tags as $tag) {
 | 
					        foreach ($tags as $tag) {
 | 
				
			||||||
            $issue->setAssoc($tag);
 | 
					            $issue->setAssoc($tag);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					        // add relations (if any)
 | 
				
			||||||
 | 
					        if (!empty($this->cleaned_data['relation_type0'])) {
 | 
				
			||||||
 | 
					            $verb = $this->cleaned_data['relation_type0'];
 | 
				
			||||||
 | 
					            $other_verb = $this->relation_types[$verb];
 | 
				
			||||||
 | 
					            $related_issues = preg_split('/\s*,\s*/', $this->cleaned_data['relation_issue0'], -1, PREG_SPLIT_NO_EMPTY);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            foreach ($related_issues as $related_issue_id) {
 | 
				
			||||||
 | 
					                $related_issue = new IDF_Issue($related_issue_id);
 | 
				
			||||||
 | 
					                $rel = new IDF_IssueRelation();
 | 
				
			||||||
 | 
					                $rel->issue = $issue;
 | 
				
			||||||
 | 
					                $rel->verb = $verb;
 | 
				
			||||||
 | 
					                $rel->other_issue = $related_issue;
 | 
				
			||||||
 | 
					                $rel->submitter = $this->user;
 | 
				
			||||||
 | 
					                $rel->create();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                $other_rel = new IDF_IssueRelation();
 | 
				
			||||||
 | 
					                $other_rel->issue = $related_issue;
 | 
				
			||||||
 | 
					                $other_rel->verb = $other_verb;
 | 
				
			||||||
 | 
					                $other_rel->other_issue = $issue;
 | 
				
			||||||
 | 
					                $other_rel->submitter = $this->user;
 | 
				
			||||||
 | 
					                $other_rel->create();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // add the first comment
 | 
					        // add the first comment
 | 
				
			||||||
        $comment = new IDF_IssueComment();
 | 
					        $comment = new IDF_IssueComment();
 | 
				
			||||||
        $comment->issue = $issue;
 | 
					        $comment->issue = $issue;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,7 +3,7 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
# ***** BEGIN LICENSE BLOCK *****
 | 
					# ***** BEGIN LICENSE BLOCK *****
 | 
				
			||||||
# This file is part of InDefero, an open source project management application.
 | 
					# This file is part of InDefero, an open source project management application.
 | 
				
			||||||
# Copyright (C) 2008 Céondo Ltd and contributors.
 | 
					# Copyright (C) 2008-2011 Céondo Ltd and contributors.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# InDefero is free software; you can redistribute it and/or modify
 | 
					# InDefero is free software; you can redistribute it and/or modify
 | 
				
			||||||
# it under the terms of the GNU General Public License as published by
 | 
					# it under the terms of the GNU General Public License as published by
 | 
				
			||||||
@@ -72,6 +72,23 @@ Performance          = Performance issue
 | 
				
			|||||||
Usability            = Affects program usability
 | 
					Usability            = Affects program usability
 | 
				
			||||||
Maintainability      = Hinders future changes';
 | 
					Maintainability      = Hinders future changes';
 | 
				
			||||||
    const init_one_max = 'Type, Priority, Milestone';
 | 
					    const init_one_max = 'Type, Priority, Milestone';
 | 
				
			||||||
 | 
					    // ATTENTION: if you change something here, change the values below as well!
 | 
				
			||||||
 | 
					    const init_relations = 'is related to
 | 
				
			||||||
 | 
					blocks, is blocked by
 | 
				
			||||||
 | 
					duplicates, is duplicated by';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // These are actually all noop's, but we have no other chance to
 | 
				
			||||||
 | 
					    // tell IDF's translation mechanism to mark the strings as translatable
 | 
				
			||||||
 | 
					    // FIXME: IDF should get a internal translation system for strings like
 | 
				
			||||||
 | 
					    // that, that can also be easily expanded by users
 | 
				
			||||||
 | 
					    private function noop()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        __('is related to');
 | 
				
			||||||
 | 
					        __('blocks');
 | 
				
			||||||
 | 
					        __('is blocked by');
 | 
				
			||||||
 | 
					        __('duplicates');
 | 
				
			||||||
 | 
					        __('is duplicated by');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function initFields($extra=array())
 | 
					    public function initFields($extra=array())
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
@@ -114,10 +131,19 @@ Maintainability      = Hinders future changes';
 | 
				
			|||||||
        $this->fields['labels_issue_one_max'] = new Pluf_Form_Field_Varchar(
 | 
					        $this->fields['labels_issue_one_max'] = new Pluf_Form_Field_Varchar(
 | 
				
			||||||
                                      array('required' => false,
 | 
					                                      array('required' => false,
 | 
				
			||||||
                                            'label' => __('Each issue may have at most one label with each of these classes'),
 | 
					                                            'label' => __('Each issue may have at most one label with each of these classes'),
 | 
				
			||||||
                                            'initial' => self::init_one_max, 
 | 
					                                            'initial' => self::init_one_max,
 | 
				
			||||||
                                            'widget_attrs' => array('size' => 60),
 | 
					                                            'widget_attrs' => array('size' => 60),
 | 
				
			||||||
                                            ));
 | 
					                                            ));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->fields['issue_relations'] = new Pluf_Form_Field_Varchar(
 | 
				
			||||||
 | 
					                                      array('required' => true,
 | 
				
			||||||
 | 
					                                            'label' => __('Issue relations'),
 | 
				
			||||||
 | 
					                                            'initial' => self::init_relations,
 | 
				
			||||||
 | 
					                                            'help_text' => __('You can define bidirectional relations like "is related to" or "blocks, is blocked by".'),
 | 
				
			||||||
 | 
					                                            'widget_attrs' => array('rows' => 7,
 | 
				
			||||||
 | 
					                                                                    'cols' => 75),
 | 
				
			||||||
 | 
					                                            'widget' => 'Pluf_Form_Widget_TextareaInput',
 | 
				
			||||||
 | 
					                                            ));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,7 +3,7 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
# ***** BEGIN LICENSE BLOCK *****
 | 
					# ***** BEGIN LICENSE BLOCK *****
 | 
				
			||||||
# This file is part of InDefero, an open source project management application.
 | 
					# This file is part of InDefero, an open source project management application.
 | 
				
			||||||
# Copyright (C) 2008 Céondo Ltd and contributors.
 | 
					# Copyright (C) 2008-2011 Céondo Ltd and contributors.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# InDefero is free software; you can redistribute it and/or modify
 | 
					# InDefero is free software; you can redistribute it and/or modify
 | 
				
			||||||
# it under the terms of the GNU General Public License as published by
 | 
					# it under the terms of the GNU General Public License as published by
 | 
				
			||||||
@@ -39,6 +39,7 @@ class IDF_Form_IssueUpdate  extends IDF_Form_IssueCreate
 | 
				
			|||||||
            or $this->user->hasPerm('IDF.project-member', $this->project)) {
 | 
					            or $this->user->hasPerm('IDF.project-member', $this->project)) {
 | 
				
			||||||
            $this->show_full = true;
 | 
					            $this->show_full = true;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					        $this->relation_types = $this->project->getRelationsFromConfig();
 | 
				
			||||||
        if ($this->show_full) {
 | 
					        if ($this->show_full) {
 | 
				
			||||||
            $this->fields['summary'] = new Pluf_Form_Field_Varchar(
 | 
					            $this->fields['summary'] = new Pluf_Form_Field_Varchar(
 | 
				
			||||||
                                      array('required' => true,
 | 
					                                      array('required' => true,
 | 
				
			||||||
@@ -69,11 +70,11 @@ class IDF_Form_IssueUpdate  extends IDF_Form_IssueCreate
 | 
				
			|||||||
        // case of someone allowing the upload path to be accessible
 | 
					        // case of someone allowing the upload path to be accessible
 | 
				
			||||||
        // to everybody.
 | 
					        // to everybody.
 | 
				
			||||||
        for ($i=1;$i<4;$i++) {
 | 
					        for ($i=1;$i<4;$i++) {
 | 
				
			||||||
            $filename = substr($md5, 0, 2).'/'.substr($md5, 2, 2).'/'.substr($md5, 4).'/%s.dummy'; 
 | 
					            $filename = substr($md5, 0, 2).'/'.substr($md5, 2, 2).'/'.substr($md5, 4).'/%s.dummy';
 | 
				
			||||||
            $this->fields['attachment'.$i] = new Pluf_Form_Field_File(
 | 
					            $this->fields['attachment'.$i] = new Pluf_Form_Field_File(
 | 
				
			||||||
                array('required' => false,
 | 
					                array('required' => false,
 | 
				
			||||||
                      'label' => __('Attach a file'),
 | 
					                      'label' => __('Attach a file'),
 | 
				
			||||||
                      'move_function_params' => 
 | 
					                      'move_function_params' =>
 | 
				
			||||||
                      array('upload_path' => $upload_path,
 | 
					                      array('upload_path' => $upload_path,
 | 
				
			||||||
                            'upload_path_create' => true,
 | 
					                            'upload_path_create' => true,
 | 
				
			||||||
                            'file_name' => $filename,
 | 
					                            'file_name' => $filename,
 | 
				
			||||||
@@ -102,6 +103,52 @@ class IDF_Form_IssueUpdate  extends IDF_Form_IssueCreate
 | 
				
			|||||||
                                                       'size' => 15,
 | 
					                                                       'size' => 15,
 | 
				
			||||||
                                                                    ),
 | 
					                                                                    ),
 | 
				
			||||||
                                            ));
 | 
					                                            ));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $idx = 0;
 | 
				
			||||||
 | 
					            // note: clean_relation_type0 and clean_relation_issue0 already
 | 
				
			||||||
 | 
					            //       exist in the base class
 | 
				
			||||||
 | 
					            $this->fields['relation_type'.$idx] = new Pluf_Form_Field_Varchar(
 | 
				
			||||||
 | 
					                          array('required' => false,
 | 
				
			||||||
 | 
					                                'label' => __('This issue'),
 | 
				
			||||||
 | 
					                                'initial' => current($this->relation_types),
 | 
				
			||||||
 | 
					                                'widget_attrs' => array('size' => 15),
 | 
				
			||||||
 | 
					                                ));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $this->fields['relation_issue'.$idx] = new Pluf_Form_Field_Varchar(
 | 
				
			||||||
 | 
					                          array('required' => false,
 | 
				
			||||||
 | 
					                                'label' => null,
 | 
				
			||||||
 | 
					                                'initial' => '',
 | 
				
			||||||
 | 
					                                'widget_attrs' => array('size' => 10),
 | 
				
			||||||
 | 
					                                ));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            ++$idx;
 | 
				
			||||||
 | 
					            $relatedIssues = $this->issue->getGroupedRelatedIssues(array(), true);
 | 
				
			||||||
 | 
					            foreach ($relatedIssues as $verb => $ids) {
 | 
				
			||||||
 | 
					                $this->fields['relation_type'.$idx] = new Pluf_Form_Field_Varchar(
 | 
				
			||||||
 | 
					                          array('required' => false,
 | 
				
			||||||
 | 
					                                'label' => __('This issue'),
 | 
				
			||||||
 | 
					                                'initial' => $verb,
 | 
				
			||||||
 | 
					                                'widget_attrs' => array('size' => 15),
 | 
				
			||||||
 | 
					                                ));
 | 
				
			||||||
 | 
					                $m = 'clean_relation_type'.$idx;
 | 
				
			||||||
 | 
					                $this->$m = create_function('$form', '
 | 
				
			||||||
 | 
					                    return $form->clean_relation_type($form->cleaned_data["relation_type'.$idx.'"]);
 | 
				
			||||||
 | 
					                ');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                $this->fields['relation_issue'.$idx] = new Pluf_Form_Field_Varchar(
 | 
				
			||||||
 | 
					                              array('required' => false,
 | 
				
			||||||
 | 
					                                    'label' => null,
 | 
				
			||||||
 | 
					                                    'initial' => implode(', ', $ids),
 | 
				
			||||||
 | 
					                                    'widget_attrs' => array('size' => 10),
 | 
				
			||||||
 | 
					                                    ));
 | 
				
			||||||
 | 
					                $m = 'clean_relation_issue'.$idx;
 | 
				
			||||||
 | 
					                $this->$m = create_function('$form', '
 | 
				
			||||||
 | 
					                    return $form->clean_relation_issue($form->cleaned_data["relation_issue'.$idx.'"]);
 | 
				
			||||||
 | 
					                ');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                ++$idx;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            $tags = $this->issue->get_tags_list();
 | 
					            $tags = $this->issue->get_tags_list();
 | 
				
			||||||
            for ($i=1;$i<7;$i++) {
 | 
					            for ($i=1;$i<7;$i++) {
 | 
				
			||||||
                $initial = '';
 | 
					                $initial = '';
 | 
				
			||||||
@@ -155,6 +202,51 @@ class IDF_Form_IssueUpdate  extends IDF_Form_IssueCreate
 | 
				
			|||||||
    public function clean()
 | 
					    public function clean()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $this->cleaned_data = parent::clean();
 | 
					        $this->cleaned_data = parent::clean();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // normalize the user's input by removing dublettes and by combining
 | 
				
			||||||
 | 
					        // ids from identical verbs in different input fields into one array
 | 
				
			||||||
 | 
					        $normRelatedIssues = array();
 | 
				
			||||||
 | 
					        for ($idx = 0; isset($this->cleaned_data['relation_type'.$idx]); ++$idx) {
 | 
				
			||||||
 | 
					            $verb = $this->cleaned_data['relation_type'.$idx];
 | 
				
			||||||
 | 
					            if (empty($verb))
 | 
				
			||||||
 | 
					                continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $ids = preg_split('/\s*,\s*/', $this->cleaned_data['relation_issue'.$idx],
 | 
				
			||||||
 | 
					                              -1, PREG_SPLIT_NO_EMPTY);
 | 
				
			||||||
 | 
					            if (count($ids) == 0)
 | 
				
			||||||
 | 
					                continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (!array_key_exists($verb, $normRelatedIssues))
 | 
				
			||||||
 | 
					                $normRelatedIssues[$verb] = array();
 | 
				
			||||||
 | 
					            foreach ($ids as $id) {
 | 
				
			||||||
 | 
					                if (!in_array($id, $normRelatedIssues[$verb]))
 | 
				
			||||||
 | 
					                    $normRelatedIssues[$verb][] = $id;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // now look at any added / removed ids
 | 
				
			||||||
 | 
					        $added = $removed = array();
 | 
				
			||||||
 | 
					        $relatedIssues = $this->issue->getGroupedRelatedIssues(array(), true);
 | 
				
			||||||
 | 
					        $added = array_diff_key($normRelatedIssues, $relatedIssues);
 | 
				
			||||||
 | 
					        $removed = array_diff_key($relatedIssues, $normRelatedIssues);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $keysToLookAt = array_keys(
 | 
				
			||||||
 | 
					            array_intersect_key($relatedIssues, $normRelatedIssues)
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					        foreach ($keysToLookAt as $key) {
 | 
				
			||||||
 | 
					            $a = array_diff($normRelatedIssues[$key], $relatedIssues[$key]);
 | 
				
			||||||
 | 
					            if (count($a) > 0)
 | 
				
			||||||
 | 
					                $added[$key] = $a;
 | 
				
			||||||
 | 
					            $r = array_diff($relatedIssues[$key], $normRelatedIssues[$key]);
 | 
				
			||||||
 | 
					            if (count($r) > 0)
 | 
				
			||||||
 | 
					                $removed[$key] = $r;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // cache the added / removed data, so we do not have to
 | 
				
			||||||
 | 
					        // calculate that again
 | 
				
			||||||
 | 
					        $this->cleaned_data['_added_issue_relations'] = $added;
 | 
				
			||||||
 | 
					        $this->cleaned_data['_removed_issue_relations'] = $removed;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // As soon as we know that at least one change was done, we
 | 
					        // As soon as we know that at least one change was done, we
 | 
				
			||||||
        // return the cleaned data and do not go further.
 | 
					        // return the cleaned data and do not go further.
 | 
				
			||||||
        if (strlen(trim($this->cleaned_data['content']))) {
 | 
					        if (strlen(trim($this->cleaned_data['content']))) {
 | 
				
			||||||
@@ -214,6 +306,11 @@ class IDF_Form_IssueUpdate  extends IDF_Form_IssueCreate
 | 
				
			|||||||
                    return $this->cleaned_data;
 | 
					                    return $this->cleaned_data;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (count($this->cleaned_data['_added_issue_relations']) != 0 ||
 | 
				
			||||||
 | 
					                count($this->cleaned_data['_removed_issue_relations']) != 0) {
 | 
				
			||||||
 | 
					                return $this->cleaned_data;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        // no changes!
 | 
					        // no changes!
 | 
				
			||||||
        throw new Pluf_Form_Invalid(__('No changes were entered.'));
 | 
					        throw new Pluf_Form_Invalid(__('No changes were entered.'));
 | 
				
			||||||
@@ -255,20 +352,22 @@ class IDF_Form_IssueUpdate  extends IDF_Form_IssueCreate
 | 
				
			|||||||
            foreach ($tags as $tag) {
 | 
					            foreach ($tags as $tag) {
 | 
				
			||||||
                if (!Pluf_Model_InArray($tag, $oldtags)) {
 | 
					                if (!Pluf_Model_InArray($tag, $oldtags)) {
 | 
				
			||||||
                    if (!isset($changes['lb'])) $changes['lb'] = array();
 | 
					                    if (!isset($changes['lb'])) $changes['lb'] = array();
 | 
				
			||||||
 | 
					                    if (!isset($changes['lb']['add'])) $changes['lb']['add'] = array();
 | 
				
			||||||
                    if ($tag->class != 'Other') {
 | 
					                    if ($tag->class != 'Other') {
 | 
				
			||||||
                        $changes['lb'][] = (string) $tag; //new tag
 | 
					                        $changes['lb']['add'][] = (string) $tag; //new tag
 | 
				
			||||||
                    } else {
 | 
					                    } else {
 | 
				
			||||||
                        $changes['lb'][] = (string) $tag->name;
 | 
					                        $changes['lb']['add'][] = (string) $tag->name;
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            foreach ($oldtags as $tag) {
 | 
					            foreach ($oldtags as $tag) {
 | 
				
			||||||
                if (!Pluf_Model_InArray($tag, $tags)) {
 | 
					                if (!Pluf_Model_InArray($tag, $tags)) {
 | 
				
			||||||
                    if (!isset($changes['lb'])) $changes['lb'] = array();
 | 
					                    if (!isset($changes['lb'])) $changes['lb'] = array();
 | 
				
			||||||
 | 
					                    if (!isset($changes['lb']['rem'])) $changes['lb']['rem'] = array();
 | 
				
			||||||
                    if ($tag->class != 'Other') {
 | 
					                    if ($tag->class != 'Other') {
 | 
				
			||||||
                        $changes['lb'][] = '-'.(string) $tag; //new tag
 | 
					                        $changes['lb']['rem'][] = (string) $tag; //new tag
 | 
				
			||||||
                    } else {
 | 
					                    } else {
 | 
				
			||||||
                        $changes['lb'][] = '-'.(string) $tag->name;
 | 
					                        $changes['lb']['rem'][] = (string) $tag->name;
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
@@ -286,6 +385,47 @@ class IDF_Form_IssueUpdate  extends IDF_Form_IssueCreate
 | 
				
			|||||||
                or ((!is_null($owner) and !is_null($this->issue->get_owner())) and $owner->id != $this->issue->get_owner()->id)) {
 | 
					                or ((!is_null($owner) and !is_null($this->issue->get_owner())) and $owner->id != $this->issue->get_owner()->id)) {
 | 
				
			||||||
                $changes['ow'] = (is_null($owner)) ? '---' : $owner->login;
 | 
					                $changes['ow'] = (is_null($owner)) ? '---' : $owner->login;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					            // Issue relations - additions
 | 
				
			||||||
 | 
					            foreach ($this->cleaned_data['_added_issue_relations'] as $verb => $ids) {
 | 
				
			||||||
 | 
					                $other_verb = $this->relation_types[$verb];
 | 
				
			||||||
 | 
					                foreach ($ids as $id) {
 | 
				
			||||||
 | 
					                    $related_issue = new IDF_Issue($id);
 | 
				
			||||||
 | 
					                    $rel = new IDF_IssueRelation();
 | 
				
			||||||
 | 
					                    $rel->issue = $this->issue;
 | 
				
			||||||
 | 
					                    $rel->verb = $verb;
 | 
				
			||||||
 | 
					                    $rel->other_issue = $related_issue;
 | 
				
			||||||
 | 
					                    $rel->submitter = $this->user;
 | 
				
			||||||
 | 
					                    $rel->create();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    $other_rel = new IDF_IssueRelation();
 | 
				
			||||||
 | 
					                    $other_rel->issue = $related_issue;
 | 
				
			||||||
 | 
					                    $other_rel->verb = $other_verb;
 | 
				
			||||||
 | 
					                    $other_rel->other_issue = $this->issue;
 | 
				
			||||||
 | 
					                    $other_rel->submitter = $this->user;
 | 
				
			||||||
 | 
					                    $other_rel->create();
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                if (!isset($changes['rel'])) $changes['rel'] = array();
 | 
				
			||||||
 | 
					                if (!isset($changes['rel']['add'])) $changes['rel']['add'] = array();
 | 
				
			||||||
 | 
					                $changes['rel']['add'][] = $verb.' '.implode(', ', $ids);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            // Issue relations - removals
 | 
				
			||||||
 | 
					            foreach ($this->cleaned_data['_removed_issue_relations'] as $verb => $ids) {
 | 
				
			||||||
 | 
					                foreach ($ids as $id) {
 | 
				
			||||||
 | 
					                    $db = &Pluf::db();
 | 
				
			||||||
 | 
					                    $table = Pluf::factory('IDF_IssueRelation')->getSqlTable();
 | 
				
			||||||
 | 
					                    $sql = new Pluf_SQL('verb=%s AND (
 | 
				
			||||||
 | 
					                                        (issue=%s AND other_issue=%s) OR
 | 
				
			||||||
 | 
					                                        (other_issue=%s AND issue=%s))',
 | 
				
			||||||
 | 
					                                        array($verb,
 | 
				
			||||||
 | 
					                                              $this->issue->id, $id,
 | 
				
			||||||
 | 
					                                              $this->issue->id, $id));
 | 
				
			||||||
 | 
					                    $db->execute('DELETE FROM '.$table.' WHERE '.$sql->gen());
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                if (!isset($changes['rel'])) $changes['rel'] = array();
 | 
				
			||||||
 | 
					                if (!isset($changes['rel']['rem'])) $changes['rel']['rem'] = array();
 | 
				
			||||||
 | 
					                $changes['rel']['rem'][] = $verb.' '.implode(', ', $ids);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
            // Update the issue
 | 
					            // Update the issue
 | 
				
			||||||
            $this->issue->batchAssoc('IDF_Tag', $tagids);
 | 
					            $this->issue->batchAssoc('IDF_Tag', $tagids);
 | 
				
			||||||
            $this->issue->summary = trim($this->cleaned_data['summary']);
 | 
					            $this->issue->summary = trim($this->cleaned_data['summary']);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,7 +3,7 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
# ***** BEGIN LICENSE BLOCK *****
 | 
					# ***** BEGIN LICENSE BLOCK *****
 | 
				
			||||||
# This file is part of InDefero, an open source project management application.
 | 
					# This file is part of InDefero, an open source project management application.
 | 
				
			||||||
# Copyright (C) 2008 Céondo Ltd and contributors.
 | 
					# Copyright (C) 2008-2011 Céondo Ltd and contributors.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# InDefero is free software; you can redistribute it and/or modify
 | 
					# InDefero is free software; you can redistribute it and/or modify
 | 
				
			||||||
# it under the terms of the GNU General Public License as published by
 | 
					# it under the terms of the GNU General Public License as published by
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,7 +3,7 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
# ***** BEGIN LICENSE BLOCK *****
 | 
					# ***** BEGIN LICENSE BLOCK *****
 | 
				
			||||||
# This file is part of InDefero, an open source project management application.
 | 
					# This file is part of InDefero, an open source project management application.
 | 
				
			||||||
# Copyright (C) 2008 Céondo Ltd and contributors.
 | 
					# Copyright (C) 2008-2011 Céondo Ltd and contributors.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# InDefero is free software; you can redistribute it and/or modify
 | 
					# InDefero is free software; you can redistribute it and/or modify
 | 
				
			||||||
# it under the terms of the GNU General Public License as published by
 | 
					# it under the terms of the GNU General Public License as published by
 | 
				
			||||||
@@ -86,7 +86,7 @@ class IDF_Form_Password extends Pluf_Form
 | 
				
			|||||||
                $return_url = Pluf_HTTP_URL_urlForView('IDF_Views::passwordRecoveryInputCode');
 | 
					                $return_url = Pluf_HTTP_URL_urlForView('IDF_Views::passwordRecoveryInputCode');
 | 
				
			||||||
                $tmpl = new Pluf_Template('idf/user/passrecovery-email.txt');
 | 
					                $tmpl = new Pluf_Template('idf/user/passrecovery-email.txt');
 | 
				
			||||||
                $cr = new Pluf_Crypt(md5(Pluf::f('secret_key')));
 | 
					                $cr = new Pluf_Crypt(md5(Pluf::f('secret_key')));
 | 
				
			||||||
                $code = trim($cr->encrypt($user->email.':'.$user->id.':'.time()), 
 | 
					                $code = trim($cr->encrypt($user->email.':'.$user->id.':'.time().':primary'), 
 | 
				
			||||||
                             '~');
 | 
					                             '~');
 | 
				
			||||||
                $code = substr(md5(Pluf::f('secret_key').$code), 0, 2).$code;
 | 
					                $code = substr(md5(Pluf::f('secret_key').$code), 0, 2).$code;
 | 
				
			||||||
                $url = Pluf::f('url_base').Pluf_HTTP_URL_urlForView('IDF_Views::passwordRecovery', array($code), array(), false);
 | 
					                $url = Pluf::f('url_base').Pluf_HTTP_URL_urlForView('IDF_Views::passwordRecovery', array($code), array(), false);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,7 +3,7 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
# ***** BEGIN LICENSE BLOCK *****
 | 
					# ***** BEGIN LICENSE BLOCK *****
 | 
				
			||||||
# This file is part of InDefero, an open source project management application.
 | 
					# This file is part of InDefero, an open source project management application.
 | 
				
			||||||
# Copyright (C) 2008 Céondo Ltd and contributors.
 | 
					# Copyright (C) 2008-2011 Céondo Ltd and contributors.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# InDefero is free software; you can redistribute it and/or modify
 | 
					# InDefero is free software; you can redistribute it and/or modify
 | 
				
			||||||
# it under the terms of the GNU General Public License as published by
 | 
					# it under the terms of the GNU General Public License as published by
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,7 +3,7 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
# ***** BEGIN LICENSE BLOCK *****
 | 
					# ***** BEGIN LICENSE BLOCK *****
 | 
				
			||||||
# This file is part of InDefero, an open source project management application.
 | 
					# This file is part of InDefero, an open source project management application.
 | 
				
			||||||
# Copyright (C) 2008 Céondo Ltd and contributors.
 | 
					# Copyright (C) 2008-2011 Céondo Ltd and contributors.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# InDefero is free software; you can redistribute it and/or modify
 | 
					# InDefero is free software; you can redistribute it and/or modify
 | 
				
			||||||
# it under the terms of the GNU General Public License as published by
 | 
					# it under the terms of the GNU General Public License as published by
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										140
									
								
								src/IDF/Form/ProjectConf.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										140
									
								
								src/IDF/Form/ProjectConf.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,140 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					/* -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					# ***** BEGIN LICENSE BLOCK *****
 | 
				
			||||||
 | 
					# This file is part of InDefero, an open source project management application.
 | 
				
			||||||
 | 
					# Copyright(C) 2008-2011 Céondo Ltd and contributors.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# InDefero is free software; you can redistribute it and/or modify
 | 
				
			||||||
 | 
					# it under the terms of the GNU General Public License as published by
 | 
				
			||||||
 | 
					# the Free Software Foundation; either version 2 of the License, or
 | 
				
			||||||
 | 
					#(at your option) any later version.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# InDefero is distributed in the hope that it will be useful,
 | 
				
			||||||
 | 
					# but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
				
			||||||
 | 
					# GNU General Public License for more details.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# You should have received a copy of the GNU General Public License
 | 
				
			||||||
 | 
					# along with this program; if not, write to the Free Software
 | 
				
			||||||
 | 
					# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# ***** END LICENSE BLOCK ***** */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Configuration of the project.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					class IDF_Form_ProjectConf extends Pluf_Form
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public $project = null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function initFields($extra=array())
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $this->project = $extra['project'];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Basic part
 | 
				
			||||||
 | 
					        $this->fields['name'] = new Pluf_Form_Field_Varchar(array('required' => true,
 | 
				
			||||||
 | 
					                                                                  'label' => __('Name'),
 | 
				
			||||||
 | 
					                                                                  'initial' => $this->project->name,
 | 
				
			||||||
 | 
					                                                                 ));
 | 
				
			||||||
 | 
					        $this->fields['shortdesc'] = new Pluf_Form_Field_Varchar(array('required' => true,
 | 
				
			||||||
 | 
					                                                                       'label' => __('Short Description'),
 | 
				
			||||||
 | 
					                                                                       'initial' => $this->project->shortdesc,
 | 
				
			||||||
 | 
					                                                                       'widget_attrs' => array('size' => '68'),
 | 
				
			||||||
 | 
					                                                                      ));
 | 
				
			||||||
 | 
					        $this->fields['description'] = new Pluf_Form_Field_Varchar(array('required' => true,
 | 
				
			||||||
 | 
					                                                                         'label' => __('Description'),
 | 
				
			||||||
 | 
					                                                                         'initial' => $this->project->description,
 | 
				
			||||||
 | 
					                                                                         'widget_attrs' => array('cols' => 68,
 | 
				
			||||||
 | 
					                                                                                                 'rows' => 26,
 | 
				
			||||||
 | 
					                                                                                                ),
 | 
				
			||||||
 | 
					                                                                         'widget' => 'Pluf_Form_Widget_TextareaInput',
 | 
				
			||||||
 | 
					                                                                        ));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Logo part
 | 
				
			||||||
 | 
					        $upload_path = Pluf::f('upload_path', false);
 | 
				
			||||||
 | 
					        if (false === $upload_path) {
 | 
				
			||||||
 | 
					            throw new Pluf_Exception_SettingError(__('The "upload_path" configuration variable was not set.'));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        $upload_path .= '/' . $this->project->shortname;
 | 
				
			||||||
 | 
					        $filename = '/%s';
 | 
				
			||||||
 | 
					        $this->fields['logo'] = new Pluf_Form_Field_File(array('required' => false,
 | 
				
			||||||
 | 
					                                                         'label' => __('Update the logo'),
 | 
				
			||||||
 | 
					                                                         'initial' => '',
 | 
				
			||||||
 | 
					                                                         'help_text' => __('The logo must be a picture with a size of 32 by 32.'),
 | 
				
			||||||
 | 
					                                                         'max_size' => Pluf::f('max_upload_size', 5 * 1024),
 | 
				
			||||||
 | 
					                                                         'move_function_params' =>
 | 
				
			||||||
 | 
					                                                         array('upload_path' => $upload_path,
 | 
				
			||||||
 | 
					                                                               'upload_path_create' => true,
 | 
				
			||||||
 | 
					                                                               'file_name' => $filename,
 | 
				
			||||||
 | 
					                                                               )
 | 
				
			||||||
 | 
					                                                         ));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->fields['logo_remove'] = new Pluf_Form_Field_Boolean(array('required' => false,
 | 
				
			||||||
 | 
					                                                                         'label' => __('Remove the current logo'),
 | 
				
			||||||
 | 
					                                                                         'initial' => false,
 | 
				
			||||||
 | 
					                                                                         'widget' => 'Pluf_Form_Widget_CheckboxInput',
 | 
				
			||||||
 | 
					                                                                         ));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * If we have uploaded a file, but the form failed remove it.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    function failed()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if (!empty($this->cleaned_data['logo'])
 | 
				
			||||||
 | 
					            && file_exists(Pluf::f('upload_path').'/'.$this->cleaned_data['logo'])) {
 | 
				
			||||||
 | 
					            unlink(Pluf::f('upload_path').'/'.$this->cleaned_data['logo']);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function clean()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if (!isset($this->cleaned_data['logo_remove'])) {
 | 
				
			||||||
 | 
					            $this->cleaned_data['logo_remove'] = false;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $this->cleaned_data;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function clean_logo()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if (empty($this->cleaned_data['logo'])) {
 | 
				
			||||||
 | 
					            return '';
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $meta = getimagesize(Pluf::f('upload_path') . '/' . $this->project->shortname . $this->cleaned_data['logo']);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ($meta === false) {
 | 
				
			||||||
 | 
					            throw new Pluf_Form_Invalid(__('Could not determine the size of the uploaded picture.'));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ($meta[0] !== 32 || $meta[1] !== 32) {
 | 
				
			||||||
 | 
					            throw new Pluf_Form_Invalid(__('The picture must have a size of 32 by 32.'));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $this->cleaned_data['logo'];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function save($commit=true)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $conf = $this->project->getConf();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Basic part
 | 
				
			||||||
 | 
					        $this->project->name = $this->cleaned_data['name'];
 | 
				
			||||||
 | 
					        $this->project->shortdesc = $this->cleaned_data['shortdesc'];
 | 
				
			||||||
 | 
					        $this->project->description = $this->cleaned_data['description'];
 | 
				
			||||||
 | 
					        $this->project->update();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Logo part
 | 
				
			||||||
 | 
					        if ($this->cleaned_data['logo'] !== "") {
 | 
				
			||||||
 | 
					            $conf->setVal('logo', $this->cleaned_data['logo']);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if ($this->cleaned_data['logo_remove'] === true) {
 | 
				
			||||||
 | 
					            @unlink(Pluf::f('upload_path') . '/' . $this->project->shortname . $conf->getVal('logo'));
 | 
				
			||||||
 | 
					            $conf->delVal('logo');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -3,7 +3,7 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
# ***** BEGIN LICENSE BLOCK *****
 | 
					# ***** BEGIN LICENSE BLOCK *****
 | 
				
			||||||
# This file is part of InDefero, an open source project management application.
 | 
					# This file is part of InDefero, an open source project management application.
 | 
				
			||||||
# Copyright (C) 2008 Céondo Ltd and contributors.
 | 
					# Copyright (C) 2008-2011 Céondo Ltd and contributors.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# InDefero is free software; you can redistribute it and/or modify
 | 
					# InDefero is free software; you can redistribute it and/or modify
 | 
				
			||||||
# it under the terms of the GNU General Public License as published by
 | 
					# it under the terms of the GNU General Public License as published by
 | 
				
			||||||
@@ -42,7 +42,7 @@ class IDF_Form_Register extends Pluf_Form
 | 
				
			|||||||
                                            'max_length' => 15,
 | 
					                                            'max_length' => 15,
 | 
				
			||||||
                                            'min_length' => 3,
 | 
					                                            'min_length' => 3,
 | 
				
			||||||
                                            'initial' => $login,
 | 
					                                            'initial' => $login,
 | 
				
			||||||
                                            'help_text' => __('The login must be between 3 and 15 characters long and contains only letters and digits.'),
 | 
					                                            'help_text' => __('The login must be between 3 and 15 characters long and contain only letters and digits.'),
 | 
				
			||||||
                                            'widget_attrs' => array(
 | 
					                                            'widget_attrs' => array(
 | 
				
			||||||
                                                       'maxlength' => 15,
 | 
					                                                       'maxlength' => 15,
 | 
				
			||||||
                                                       'size' => 10,
 | 
					                                                       'size' => 10,
 | 
				
			||||||
@@ -52,7 +52,7 @@ class IDF_Form_Register extends Pluf_Form
 | 
				
			|||||||
                                      array('required' => true,
 | 
					                                      array('required' => true,
 | 
				
			||||||
                                            'label' => __('Your email'),
 | 
					                                            'label' => __('Your email'),
 | 
				
			||||||
                                            'initial' => '',
 | 
					                                            'initial' => '',
 | 
				
			||||||
                                            'help_text' => __('We will never send you any unsolicited emails. We hate spams too!'),
 | 
					                                            'help_text' => __('We will never send you any unsolicited emails. We hate spam too!'),
 | 
				
			||||||
                                            ));
 | 
					                                            ));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $this->fields['terms'] = new Pluf_Form_Field_Boolean(
 | 
					        $this->fields['terms'] = new Pluf_Form_Field_Boolean(
 | 
				
			||||||
@@ -93,10 +93,8 @@ class IDF_Form_Register extends Pluf_Form
 | 
				
			|||||||
    function clean_email()
 | 
					    function clean_email()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $this->cleaned_data['email'] = mb_strtolower(trim($this->cleaned_data['email']));
 | 
					        $this->cleaned_data['email'] = mb_strtolower(trim($this->cleaned_data['email']));
 | 
				
			||||||
        $guser = new Pluf_User();
 | 
					        if (Pluf::factory('IDF_EmailAddress')->get_user_for_email_address($this->cleaned_data['email']) != null) {
 | 
				
			||||||
        $sql = new Pluf_SQL('email=%s', $this->cleaned_data['email']);
 | 
					            throw new Pluf_Form_Invalid(sprintf(__('The email "%s" is already used. If you need to, click on the help link to recover your password.'), $this->cleaned_data['email']));
 | 
				
			||||||
        if ($guser->getCount(array('filter' => $sql->gen())) > 0) {
 | 
					 | 
				
			||||||
            throw new Pluf_Form_Invalid(sprintf(__('The email "%s" is already used. If you need, click on the help link to recover your password.'), $this->cleaned_data['email']));
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        return $this->cleaned_data['email'];
 | 
					        return $this->cleaned_data['email'];
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,7 +3,7 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
# ***** BEGIN LICENSE BLOCK *****
 | 
					# ***** BEGIN LICENSE BLOCK *****
 | 
				
			||||||
# This file is part of InDefero, an open source project management application.
 | 
					# This file is part of InDefero, an open source project management application.
 | 
				
			||||||
# Copyright (C) 2008 Céondo Ltd and contributors.
 | 
					# Copyright (C) 2008-2011 Céondo Ltd and contributors.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# InDefero is free software; you can redistribute it and/or modify
 | 
					# InDefero is free software; you can redistribute it and/or modify
 | 
				
			||||||
# it under the terms of the GNU General Public License as published by
 | 
					# it under the terms of the GNU General Public License as published by
 | 
				
			||||||
@@ -69,7 +69,7 @@ class IDF_Form_RegisterConfirmation extends Pluf_Form
 | 
				
			|||||||
                                            'label' => __('Your password'),
 | 
					                                            'label' => __('Your password'),
 | 
				
			||||||
                                            'initial' => '',
 | 
					                                            'initial' => '',
 | 
				
			||||||
                                            'widget' => 'Pluf_Form_Widget_PasswordInput',
 | 
					                                            'widget' => 'Pluf_Form_Widget_PasswordInput',
 | 
				
			||||||
                                            'help_text' => __('Your password must be hard for other people to find it, but easy for you to remember.'),
 | 
					                                            'help_text' => __('Your password must be hard for other people to guess, but easy for you to remember.'),
 | 
				
			||||||
                                            'widget_attrs' => array(
 | 
					                                            'widget_attrs' => array(
 | 
				
			||||||
                                                       'maxlength' => 50,
 | 
					                                                       'maxlength' => 50,
 | 
				
			||||||
                                                       'size' => 15,
 | 
					                                                       'size' => 15,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,7 +3,7 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
# ***** BEGIN LICENSE BLOCK *****
 | 
					# ***** BEGIN LICENSE BLOCK *****
 | 
				
			||||||
# This file is part of InDefero, an open source project management application.
 | 
					# This file is part of InDefero, an open source project management application.
 | 
				
			||||||
# Copyright (C) 2008 Céondo Ltd and contributors.
 | 
					# Copyright (C) 2008-2011 Céondo Ltd and contributors.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# InDefero is free software; you can redistribute it and/or modify
 | 
					# InDefero is free software; you can redistribute it and/or modify
 | 
				
			||||||
# it under the terms of the GNU General Public License as published by
 | 
					# it under the terms of the GNU General Public License as published by
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,7 +3,7 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
# ***** BEGIN LICENSE BLOCK *****
 | 
					# ***** BEGIN LICENSE BLOCK *****
 | 
				
			||||||
# This file is part of InDefero, an open source project management application.
 | 
					# This file is part of InDefero, an open source project management application.
 | 
				
			||||||
# Copyright (C) 2008 Céondo Ltd and contributors.
 | 
					# Copyright (C) 2008-2011 Céondo Ltd and contributors.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# InDefero is free software; you can redistribute it and/or modify
 | 
					# InDefero is free software; you can redistribute it and/or modify
 | 
				
			||||||
# it under the terms of the GNU General Public License as published by
 | 
					# it under the terms of the GNU General Public License as published by
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,7 +3,7 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
# ***** BEGIN LICENSE BLOCK *****
 | 
					# ***** BEGIN LICENSE BLOCK *****
 | 
				
			||||||
# This file is part of InDefero, an open source project management application.
 | 
					# This file is part of InDefero, an open source project management application.
 | 
				
			||||||
# Copyright (C) 2008 Céondo Ltd and contributors.
 | 
					# Copyright (C) 2008-2011 Céondo Ltd and contributors.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# InDefero is free software; you can redistribute it and/or modify
 | 
					# InDefero is free software; you can redistribute it and/or modify
 | 
				
			||||||
# it under the terms of the GNU General Public License as published by
 | 
					# it under the terms of the GNU General Public License as published by
 | 
				
			||||||
@@ -52,7 +52,7 @@ class IDF_Form_ReviewFileComment extends Pluf_Form
 | 
				
			|||||||
                                            ));
 | 
					                                            ));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        $this->fields['content'] = new Pluf_Form_Field_Varchar(
 | 
					        $this->fields['content'] = new Pluf_Form_Field_Varchar(
 | 
				
			||||||
                                      array('required' => true,
 | 
					                                      array('required' => false,
 | 
				
			||||||
                                            'label' => __('General comment'),
 | 
					                                            'label' => __('General comment'),
 | 
				
			||||||
                                            'initial' => '',
 | 
					                                            'initial' => '',
 | 
				
			||||||
                                            'widget' => 'Pluf_Form_Widget_TextareaInput',
 | 
					                                            'widget' => 'Pluf_Form_Widget_TextareaInput',
 | 
				
			||||||
@@ -64,6 +64,8 @@ class IDF_Form_ReviewFileComment extends Pluf_Form
 | 
				
			|||||||
        if ($this->user->hasPerm('IDF.project-owner', $this->project)
 | 
					        if ($this->user->hasPerm('IDF.project-owner', $this->project)
 | 
				
			||||||
            or $this->user->hasPerm('IDF.project-member', $this->project)) {
 | 
					            or $this->user->hasPerm('IDF.project-member', $this->project)) {
 | 
				
			||||||
            $this->show_full = true;
 | 
					            $this->show_full = true;
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            $this->show_full = false;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        if ($this->show_full) {
 | 
					        if ($this->show_full) {
 | 
				
			||||||
            $this->fields['summary'] = new Pluf_Form_Field_Varchar(
 | 
					            $this->fields['summary'] = new Pluf_Form_Field_Varchar(
 | 
				
			||||||
@@ -94,24 +96,40 @@ class IDF_Form_ReviewFileComment extends Pluf_Form
 | 
				
			|||||||
     */
 | 
					     */
 | 
				
			||||||
    public function clean()
 | 
					    public function clean()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        foreach ($this->files as $filename => $def) {
 | 
					        $isOk = false;
 | 
				
			||||||
            if (!empty($this->cleaned_data[md5($filename)])) {
 | 
					        
 | 
				
			||||||
                return $this->cleaned_data;
 | 
					        foreach($this->files as $filename => $def) {
 | 
				
			||||||
 | 
					            $this->cleaned_data[md5($filename)] = trim($this->cleaned_data[md5($filename)]);
 | 
				
			||||||
 | 
					            if(!empty($this->cleaned_data[md5($filename)])) {
 | 
				
			||||||
 | 
					                $isOk = true;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        throw new Pluf_Form_Invalid(__('You need to provide comments on at least one file.'));
 | 
					        
 | 
				
			||||||
 | 
					        if(!empty($this->cleaned_data['content'])) {
 | 
				
			||||||
 | 
					            $isOk = true;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        if (!$isOk) {
 | 
				
			||||||
 | 
					            throw new Pluf_Form_Invalid(__('You need to provide your general comment about the proposal, or comments on at least one file.'));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        return $this->cleaned_data;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    function clean_content()
 | 
					    function clean_content()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $content = trim($this->cleaned_data['content']);
 | 
					        $content = trim($this->cleaned_data['content']);
 | 
				
			||||||
        if (!$this->show_full and strlen($content) == 0) {
 | 
					        if(empty($content)) {
 | 
				
			||||||
            throw new Pluf_Form_Invalid(__('You need to provide your general comment about the proposal.'));
 | 
					            if ($this->fields['status']->initial != $this->fields['status']->value) {
 | 
				
			||||||
 | 
					                return __('The status have been updated.');
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            return $content;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        return $content;
 | 
					        
 | 
				
			||||||
 | 
					        throw new Pluf_Form_Invalid(__('This field is required.'));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Save the model in the database.
 | 
					     * Save the model in the database.
 | 
				
			||||||
     *
 | 
					     *
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,7 +3,7 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
# ***** BEGIN LICENSE BLOCK *****
 | 
					# ***** BEGIN LICENSE BLOCK *****
 | 
				
			||||||
# This file is part of InDefero, an open source project management application.
 | 
					# This file is part of InDefero, an open source project management application.
 | 
				
			||||||
# Copyright (C) 2008 Céondo Ltd and contributors.
 | 
					# Copyright (C) 2008-2011 Céondo Ltd and contributors.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# InDefero is free software; you can redistribute it and/or modify
 | 
					# InDefero is free software; you can redistribute it and/or modify
 | 
				
			||||||
# it under the terms of the GNU General Public License as published by
 | 
					# it under the terms of the GNU General Public License as published by
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,7 +3,7 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
# ***** BEGIN LICENSE BLOCK *****
 | 
					# ***** BEGIN LICENSE BLOCK *****
 | 
				
			||||||
# This file is part of InDefero, an open source project management application.
 | 
					# This file is part of InDefero, an open source project management application.
 | 
				
			||||||
# Copyright (C) 2008 Céondo Ltd and contributors.
 | 
					# Copyright (C) 2008-2011 Céondo Ltd and contributors.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# InDefero is free software; you can redistribute it and/or modify
 | 
					# InDefero is free software; you can redistribute it and/or modify
 | 
				
			||||||
# it under the terms of the GNU General Public License as published by
 | 
					# it under the terms of the GNU General Public License as published by
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,7 +3,7 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
# ***** BEGIN LICENSE BLOCK *****
 | 
					# ***** BEGIN LICENSE BLOCK *****
 | 
				
			||||||
# This file is part of InDefero, an open source project management application.
 | 
					# This file is part of InDefero, an open source project management application.
 | 
				
			||||||
# Copyright (C) 2008 Céondo Ltd and contributors.
 | 
					# Copyright (C) 2008-2011 Céondo Ltd and contributors.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# InDefero is free software; you can redistribute it and/or modify
 | 
					# InDefero is free software; you can redistribute it and/or modify
 | 
				
			||||||
# it under the terms of the GNU General Public License as published by
 | 
					# it under the terms of the GNU General Public License as published by
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,7 +3,7 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
# ***** BEGIN LICENSE BLOCK *****
 | 
					# ***** BEGIN LICENSE BLOCK *****
 | 
				
			||||||
# This file is part of InDefero, an open source project management application.
 | 
					# This file is part of InDefero, an open source project management application.
 | 
				
			||||||
# Copyright (C) 2008 Céondo Ltd and contributors.
 | 
					# Copyright (C) 2008-2011 Céondo Ltd and contributors.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# InDefero is free software; you can redistribute it and/or modify
 | 
					# InDefero is free software; you can redistribute it and/or modify
 | 
				
			||||||
# it under the terms of the GNU General Public License as published by
 | 
					# it under the terms of the GNU General Public License as published by
 | 
				
			||||||
@@ -83,7 +83,7 @@ class IDF_Form_Upload extends Pluf_Form
 | 
				
			|||||||
        if (strlen($extra)) $extra .= '|';
 | 
					        if (strlen($extra)) $extra .= '|';
 | 
				
			||||||
        if (!preg_match('/\.('.$extra.'png|jpg|jpeg|gif|bmp|psd|tif|aiff|asf|avi|bz2|css|doc|eps|gz|jar|mdtext|mid|mov|mp3|mpg|ogg|pdf|ppt|ps|qt|ra|ram|rm|rtf|sdd|sdw|sit|sxi|sxw|swf|tgz|txt|wav|xls|xml|war|wmv|zip)$/i', $this->cleaned_data['file'])) {
 | 
					        if (!preg_match('/\.('.$extra.'png|jpg|jpeg|gif|bmp|psd|tif|aiff|asf|avi|bz2|css|doc|eps|gz|jar|mdtext|mid|mov|mp3|mpg|ogg|pdf|ppt|ps|qt|ra|ram|rm|rtf|sdd|sdw|sit|sxi|sxw|swf|tgz|txt|wav|xls|xml|war|wmv|zip)$/i', $this->cleaned_data['file'])) {
 | 
				
			||||||
            @unlink(Pluf::f('upload_path').'/'.$this->project->shortname.'/files/'.$this->cleaned_data['file']);
 | 
					            @unlink(Pluf::f('upload_path').'/'.$this->project->shortname.'/files/'.$this->cleaned_data['file']);
 | 
				
			||||||
            throw new Pluf_Form_Invalid(__('For security reason, you cannot upload a file with this extension.'));
 | 
					            throw new Pluf_Form_Invalid(__('For security reasons, you cannot upload a file with this extension.'));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        return $this->cleaned_data['file'];
 | 
					        return $this->cleaned_data['file'];
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,7 +3,7 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
# ***** BEGIN LICENSE BLOCK *****
 | 
					# ***** BEGIN LICENSE BLOCK *****
 | 
				
			||||||
# This file is part of InDefero, an open source project management application.
 | 
					# This file is part of InDefero, an open source project management application.
 | 
				
			||||||
# Copyright (C) 2008 Céondo Ltd and contributors.
 | 
					# Copyright (C) 2008-2011 Céondo Ltd and contributors.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# InDefero is free software; you can redistribute it and/or modify
 | 
					# InDefero is free software; you can redistribute it and/or modify
 | 
				
			||||||
# it under the terms of the GNU General Public License as published by
 | 
					# it under the terms of the GNU General Public License as published by
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,7 +3,7 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
# ***** BEGIN LICENSE BLOCK *****
 | 
					# ***** BEGIN LICENSE BLOCK *****
 | 
				
			||||||
# This file is part of InDefero, an open source project management application.
 | 
					# This file is part of InDefero, an open source project management application.
 | 
				
			||||||
# Copyright (C) 2008 Céondo Ltd and contributors.
 | 
					# Copyright (C) 2008-2011 Céondo Ltd and contributors.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# InDefero is free software; you can redistribute it and/or modify
 | 
					# InDefero is free software; you can redistribute it and/or modify
 | 
				
			||||||
# it under the terms of the GNU General Public License as published by
 | 
					# it under the terms of the GNU General Public License as published by
 | 
				
			||||||
@@ -79,6 +79,7 @@ class IDF_Form_UserAccount  extends Pluf_Form
 | 
				
			|||||||
                                            'widget' => 'Pluf_Form_Widget_PasswordInput',
 | 
					                                            'widget' => 'Pluf_Form_Widget_PasswordInput',
 | 
				
			||||||
                                            'help_text' => Pluf_Template::markSafe(__('Leave blank if you do not want to change your password.').'<br />'.__('Your password must be hard for other people to find it, but easy for you to remember.')),
 | 
					                                            'help_text' => Pluf_Template::markSafe(__('Leave blank if you do not want to change your password.').'<br />'.__('Your password must be hard for other people to find it, but easy for you to remember.')),
 | 
				
			||||||
                                            'widget_attrs' => array(
 | 
					                                            'widget_attrs' => array(
 | 
				
			||||||
 | 
					                                                       'autocomplete' => 'off',
 | 
				
			||||||
                                                       'maxlength' => 50,
 | 
					                                                       'maxlength' => 50,
 | 
				
			||||||
                                                       'size' => 15,
 | 
					                                                       'size' => 15,
 | 
				
			||||||
                                                                    ),
 | 
					                                                                    ),
 | 
				
			||||||
@@ -89,6 +90,7 @@ class IDF_Form_UserAccount  extends Pluf_Form
 | 
				
			|||||||
                                            'initial' => '',
 | 
					                                            'initial' => '',
 | 
				
			||||||
                                            'widget' => 'Pluf_Form_Widget_PasswordInput',
 | 
					                                            'widget' => 'Pluf_Form_Widget_PasswordInput',
 | 
				
			||||||
                                            'widget_attrs' => array(
 | 
					                                            'widget_attrs' => array(
 | 
				
			||||||
 | 
					                                                       'autocomplete' => 'off',
 | 
				
			||||||
                                                       'maxlength' => 50,
 | 
					                                                       'maxlength' => 50,
 | 
				
			||||||
                                                       'size' => 15,
 | 
					                                                       'size' => 15,
 | 
				
			||||||
                                                                    ),
 | 
					                                                                    ),
 | 
				
			||||||
@@ -161,8 +163,44 @@ class IDF_Form_UserAccount  extends Pluf_Form
 | 
				
			|||||||
                                            'widget_attrs' => array('rows' => 3,
 | 
					                                            'widget_attrs' => array('rows' => 3,
 | 
				
			||||||
                                                                    'cols' => 40),
 | 
					                                                                    'cols' => 40),
 | 
				
			||||||
                                            'widget' => 'Pluf_Form_Widget_TextareaInput',
 | 
					                                            'widget' => 'Pluf_Form_Widget_TextareaInput',
 | 
				
			||||||
                                            'help_text' => __('Paste a SSH or monotone public key. Be careful to not provide your private key here!')
 | 
					                                            'help_text' => __('Paste an SSH or monotone public key. Be careful to not provide your private key here!')
 | 
				
			||||||
                                            ));
 | 
					                                            ));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->fields['secondary_mail'] = new Pluf_Form_Field_Email(
 | 
				
			||||||
 | 
					                                      array('required' => false,
 | 
				
			||||||
 | 
					                                            'label' => __('Add a secondary mail address'),
 | 
				
			||||||
 | 
					                                            'initial' => '',
 | 
				
			||||||
 | 
					                                            'help_text' => __('You will get a mail to confirm that you own the address you specify.'),
 | 
				
			||||||
 | 
					                                            ));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private function send_validation_mail($new_email, $secondary_mail=false)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if ($secondary_mail) {
 | 
				
			||||||
 | 
					            $type = "secondary";
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            $type = "primary";
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        $cr = new Pluf_Crypt(md5(Pluf::f('secret_key')));
 | 
				
			||||||
 | 
					        $encrypted = trim($cr->encrypt($new_email.':'.$this->user->id.':'.time().':'.$type), '~');
 | 
				
			||||||
 | 
					        $key = substr(md5(Pluf::f('secret_key').$encrypted), 0, 2).$encrypted;
 | 
				
			||||||
 | 
					        $url = Pluf::f('url_base').Pluf_HTTP_URL_urlForView('IDF_Views_User::changeEmailDo', array($key), array(), false);
 | 
				
			||||||
 | 
					        $urlik = Pluf::f('url_base').Pluf_HTTP_URL_urlForView('IDF_Views_User::changeEmailInputKey', array(), array(), false);
 | 
				
			||||||
 | 
					        $context = new Pluf_Template_Context(
 | 
				
			||||||
 | 
					             array('key' => Pluf_Template::markSafe($key),
 | 
				
			||||||
 | 
					                   'url' => Pluf_Template::markSafe($url),
 | 
				
			||||||
 | 
					                   'urlik' => Pluf_Template::markSafe($urlik),
 | 
				
			||||||
 | 
					                   'email' => $new_email,
 | 
				
			||||||
 | 
					                   'user'=> $this->user,
 | 
				
			||||||
 | 
					                   )
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					        $tmpl = new Pluf_Template('idf/user/changeemail-email.txt');
 | 
				
			||||||
 | 
					        $text_email = $tmpl->render($context);
 | 
				
			||||||
 | 
					        $email = new Pluf_Mail(Pluf::f('from_email'), $new_email,
 | 
				
			||||||
 | 
					                               __('Confirm your new email address.'));
 | 
				
			||||||
 | 
					        $email->addTextMessage($text_email);
 | 
				
			||||||
 | 
					        $email->sendMail();
 | 
				
			||||||
 | 
					        $this->user->setMessage(sprintf(__('A validation email has been sent to "%s" to validate the email address change.'), Pluf_esc($new_email)));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
@@ -188,26 +226,7 @@ class IDF_Form_UserAccount  extends Pluf_Form
 | 
				
			|||||||
        $new_email = $this->cleaned_data['email'];
 | 
					        $new_email = $this->cleaned_data['email'];
 | 
				
			||||||
        unset($this->cleaned_data['email']);
 | 
					        unset($this->cleaned_data['email']);
 | 
				
			||||||
        if ($old_email != $new_email) {
 | 
					        if ($old_email != $new_email) {
 | 
				
			||||||
            $cr = new Pluf_Crypt(md5(Pluf::f('secret_key')));
 | 
					            $this->send_validation_mail($new_email);
 | 
				
			||||||
            $encrypted = trim($cr->encrypt($new_email.':'.$this->user->id.':'.time()), '~');
 | 
					 | 
				
			||||||
            $key = substr(md5(Pluf::f('secret_key').$encrypted), 0, 2).$encrypted;
 | 
					 | 
				
			||||||
            $url = Pluf::f('url_base').Pluf_HTTP_URL_urlForView('IDF_Views_User::changeEmailDo', array($key), array(), false);
 | 
					 | 
				
			||||||
            $urlik = Pluf::f('url_base').Pluf_HTTP_URL_urlForView('IDF_Views_User::changeEmailInputKey', array(), array(), false);
 | 
					 | 
				
			||||||
            $context = new Pluf_Template_Context(
 | 
					 | 
				
			||||||
                 array('key' => Pluf_Template::markSafe($key),
 | 
					 | 
				
			||||||
                       'url' => Pluf_Template::markSafe($url),
 | 
					 | 
				
			||||||
                       'urlik' => Pluf_Template::markSafe($urlik),
 | 
					 | 
				
			||||||
                       'email' => $new_email,
 | 
					 | 
				
			||||||
                       'user'=> $this->user,
 | 
					 | 
				
			||||||
                       )
 | 
					 | 
				
			||||||
            );
 | 
					 | 
				
			||||||
            $tmpl = new Pluf_Template('idf/user/changeemail-email.txt');
 | 
					 | 
				
			||||||
            $text_email = $tmpl->render($context);
 | 
					 | 
				
			||||||
            $email = new Pluf_Mail(Pluf::f('from_email'), $new_email,
 | 
					 | 
				
			||||||
                                   __('Confirm your new email address.'));
 | 
					 | 
				
			||||||
            $email->addTextMessage($text_email);
 | 
					 | 
				
			||||||
            $email->sendMail();
 | 
					 | 
				
			||||||
            $this->user->setMessage(sprintf(__('A validation email has been sent to "%s" to validate the email address change.'), Pluf_esc($new_email)));
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        $this->user->setFromFormData($this->cleaned_data);
 | 
					        $this->user->setFromFormData($this->cleaned_data);
 | 
				
			||||||
        // Add key as needed.
 | 
					        // Add key as needed.
 | 
				
			||||||
@@ -219,6 +238,9 @@ class IDF_Form_UserAccount  extends Pluf_Form
 | 
				
			|||||||
                $key->create();
 | 
					                $key->create();
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					        if ('' !== $this->cleaned_data['secondary_mail']) {
 | 
				
			||||||
 | 
					            $this->send_validation_mail($this->cleaned_data['secondary_mail'], true);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if ($commit) {
 | 
					        if ($commit) {
 | 
				
			||||||
            $this->user->update();
 | 
					            $this->user->update();
 | 
				
			||||||
@@ -295,8 +317,15 @@ class IDF_Form_UserAccount  extends Pluf_Form
 | 
				
			|||||||
            return '';
 | 
					            return '';
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (preg_match('#^ssh\-[a-z]{3}\s\S+(\s\S+)?$#', $key)) {
 | 
					        $keysearch = '';
 | 
				
			||||||
            $key = str_replace(array("\n", "\r"), '', $key);
 | 
					        if (preg_match('#^(ssh\-(?:dss|rsa)\s+\S+)(.*)#', $key, $m)) {
 | 
				
			||||||
 | 
					            $basekey = preg_replace('/\s+/', ' ', $m[1]);
 | 
				
			||||||
 | 
					            $comment = trim(preg_replace('/[\r\n]/', ' ', $m[2]));
 | 
				
			||||||
 | 
					           
 | 
				
			||||||
 | 
					            $keysearch = $basekey.'%';
 | 
				
			||||||
 | 
					            $key = $basekey;
 | 
				
			||||||
 | 
					            if (!empty($comment))
 | 
				
			||||||
 | 
					                $key .= ' '.$comment;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (Pluf::f('idf_strong_key_check', false)) {
 | 
					            if (Pluf::f('idf_strong_key_check', false)) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -315,7 +344,9 @@ class IDF_Form_UserAccount  extends Pluf_Form
 | 
				
			|||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        else if (preg_match('#^\[pubkey [^\]]+\]\s*\S+\s*\[end\]$#', $key)) {
 | 
					        else if (preg_match('#^\[pubkey [^\]]+\]\s*(\S+)\s*\[end\]$#', $key, $m)) {
 | 
				
			||||||
 | 
					            $keysearch = '%'.$m[1].'%';
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
            if (Pluf::f('idf_strong_key_check', false)) {
 | 
					            if (Pluf::f('idf_strong_key_check', false)) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                // if monotone can read it, it should be valid
 | 
					                // if monotone can read it, it should be valid
 | 
				
			||||||
@@ -337,7 +368,7 @@ class IDF_Form_UserAccount  extends Pluf_Form
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
        else {
 | 
					        else {
 | 
				
			||||||
            throw new Pluf_Form_Invalid(
 | 
					            throw new Pluf_Form_Invalid(
 | 
				
			||||||
                __('Public key looks neither like a SSH '.
 | 
					                __('Public key looks like neither an SSH '.
 | 
				
			||||||
                   'nor monotone public key.'));
 | 
					                   'nor monotone public key.'));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -345,7 +376,7 @@ class IDF_Form_UserAccount  extends Pluf_Form
 | 
				
			|||||||
        if ($user) {
 | 
					        if ($user) {
 | 
				
			||||||
            $ruser = Pluf::factory('Pluf_User', $user);
 | 
					            $ruser = Pluf::factory('Pluf_User', $user);
 | 
				
			||||||
            if ($ruser->id > 0) {
 | 
					            if ($ruser->id > 0) {
 | 
				
			||||||
                $sql = new Pluf_SQL('content=%s', array($key));
 | 
					                $sql = new Pluf_SQL('content LIKE %s AND user=%s', array($keysearch, $ruser->id));
 | 
				
			||||||
                $keys = Pluf::factory('IDF_Key')->getList(array('filter' => $sql->gen()));
 | 
					                $keys = Pluf::factory('IDF_Key')->getList(array('filter' => $sql->gen()));
 | 
				
			||||||
                if (count($keys) > 0) {
 | 
					                if (count($keys) > 0) {
 | 
				
			||||||
                    throw new Pluf_Form_Invalid(
 | 
					                    throw new Pluf_Form_Invalid(
 | 
				
			||||||
@@ -393,15 +424,22 @@ class IDF_Form_UserAccount  extends Pluf_Form
 | 
				
			|||||||
    function clean_email()
 | 
					    function clean_email()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $this->cleaned_data['email'] = mb_strtolower(trim($this->cleaned_data['email']));
 | 
					        $this->cleaned_data['email'] = mb_strtolower(trim($this->cleaned_data['email']));
 | 
				
			||||||
        $guser = new Pluf_User();
 | 
					        $user = Pluf::factory('IDF_EmailAddress')->get_user_for_email_address($this->cleaned_data['email']);
 | 
				
			||||||
        $sql = new Pluf_SQL('email=%s AND id!=%s',
 | 
					        if ($user != null and $user->id != $this->user->id) {
 | 
				
			||||||
                            array($this->cleaned_data['email'], $this->user->id));
 | 
					 | 
				
			||||||
        if ($guser->getCount(array('filter' => $sql->gen())) > 0) {
 | 
					 | 
				
			||||||
            throw new Pluf_Form_Invalid(sprintf(__('The email "%s" is already used.'), $this->cleaned_data['email']));
 | 
					            throw new Pluf_Form_Invalid(sprintf(__('The email "%s" is already used.'), $this->cleaned_data['email']));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        return $this->cleaned_data['email'];
 | 
					        return $this->cleaned_data['email'];
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    function clean_secondary_mail()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $this->cleaned_data['secondary_mail'] = mb_strtolower(trim($this->cleaned_data['secondary_mail']));
 | 
				
			||||||
 | 
					        if (Pluf::factory('IDF_EmailAddress')->get_user_for_email_address($this->cleaned_data['secondary_mail']) != null) {
 | 
				
			||||||
 | 
					            throw new Pluf_Form_Invalid(sprintf(__('The email "%s" is already used.'), $this->cleaned_data['secondary_mail']));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return $this->cleaned_data['secondary_mail'];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    function clean_public_key()
 | 
					    function clean_public_key()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $this->cleaned_data['public_key'] =
 | 
					        $this->cleaned_data['public_key'] =
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,7 +3,7 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
# ***** BEGIN LICENSE BLOCK *****
 | 
					# ***** BEGIN LICENSE BLOCK *****
 | 
				
			||||||
# This file is part of InDefero, an open source project management application.
 | 
					# This file is part of InDefero, an open source project management application.
 | 
				
			||||||
# Copyright (C) 2008 Céondo Ltd and contributors.
 | 
					# Copyright (C) 2008-2011 Céondo Ltd and contributors.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# InDefero is free software; you can redistribute it and/or modify
 | 
					# InDefero is free software; you can redistribute it and/or modify
 | 
				
			||||||
# it under the terms of the GNU General Public License as published by
 | 
					# it under the terms of the GNU General Public License as published by
 | 
				
			||||||
@@ -53,7 +53,7 @@ class IDF_Form_UserChangeEmail extends Pluf_Form
 | 
				
			|||||||
     * Throw a Pluf_Form_Invalid exception if the key is not valid.
 | 
					     * Throw a Pluf_Form_Invalid exception if the key is not valid.
 | 
				
			||||||
     *
 | 
					     *
 | 
				
			||||||
     * @param string Key
 | 
					     * @param string Key
 | 
				
			||||||
     * @return array array($new_email, $user_id, time())
 | 
					     * @return array array($new_email, $user_id, time(), [primary|secondary])
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public static function validateKey($key)
 | 
					    public static function validateKey($key)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
@@ -63,7 +63,7 @@ class IDF_Form_UserChangeEmail extends Pluf_Form
 | 
				
			|||||||
            throw new Pluf_Form_Invalid(__('The validation key is not valid. Please copy/paste it from your confirmation email.'));
 | 
					            throw new Pluf_Form_Invalid(__('The validation key is not valid. Please copy/paste it from your confirmation email.'));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        $cr = new Pluf_Crypt(md5(Pluf::f('secret_key')));
 | 
					        $cr = new Pluf_Crypt(md5(Pluf::f('secret_key')));
 | 
				
			||||||
        return explode(':', $cr->decrypt($encrypted), 3);
 | 
					        return explode(':', $cr->decrypt($encrypted), 4);
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,7 +3,7 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
# ***** BEGIN LICENSE BLOCK *****
 | 
					# ***** BEGIN LICENSE BLOCK *****
 | 
				
			||||||
# This file is part of InDefero, an open source project management application.
 | 
					# This file is part of InDefero, an open source project management application.
 | 
				
			||||||
# Copyright (C) 2008 Céondo Ltd and contributors.
 | 
					# Copyright (C) 2008-2011 Céondo Ltd and contributors.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# InDefero is free software; you can redistribute it and/or modify
 | 
					# InDefero is free software; you can redistribute it and/or modify
 | 
				
			||||||
# it under the terms of the GNU General Public License as published by
 | 
					# it under the terms of the GNU General Public License as published by
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,7 +3,7 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
# ***** BEGIN LICENSE BLOCK *****
 | 
					# ***** BEGIN LICENSE BLOCK *****
 | 
				
			||||||
# This file is part of InDefero, an open source project management application.
 | 
					# This file is part of InDefero, an open source project management application.
 | 
				
			||||||
# Copyright (C) 2008 Céondo Ltd and contributors.
 | 
					# Copyright (C) 2008-2011 Céondo Ltd and contributors.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# InDefero is free software; you can redistribute it and/or modify
 | 
					# InDefero is free software; you can redistribute it and/or modify
 | 
				
			||||||
# it under the terms of the GNU General Public License as published by
 | 
					# it under the terms of the GNU General Public License as published by
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,7 +3,7 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
# ***** BEGIN LICENSE BLOCK *****
 | 
					# ***** BEGIN LICENSE BLOCK *****
 | 
				
			||||||
# This file is part of InDefero, an open source project management application.
 | 
					# This file is part of InDefero, an open source project management application.
 | 
				
			||||||
# Copyright (C) 2008 Céondo Ltd and contributors.
 | 
					# Copyright (C) 2008-2011 Céondo Ltd and contributors.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# InDefero is free software; you can redistribute it and/or modify
 | 
					# InDefero is free software; you can redistribute it and/or modify
 | 
				
			||||||
# it under the terms of the GNU General Public License as published by
 | 
					# it under the terms of the GNU General Public License as published by
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,7 +3,7 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
# ***** BEGIN LICENSE BLOCK *****
 | 
					# ***** BEGIN LICENSE BLOCK *****
 | 
				
			||||||
# This file is part of InDefero, an open source project management application.
 | 
					# This file is part of InDefero, an open source project management application.
 | 
				
			||||||
# Copyright (C) 2008 Céondo Ltd and contributors.
 | 
					# Copyright (C) 2008-2011 Céondo Ltd and contributors.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# InDefero is free software; you can redistribute it and/or modify
 | 
					# InDefero is free software; you can redistribute it and/or modify
 | 
				
			||||||
# it under the terms of the GNU General Public License as published by
 | 
					# it under the terms of the GNU General Public License as published by
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,7 +3,7 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
# ***** BEGIN LICENSE BLOCK *****
 | 
					# ***** BEGIN LICENSE BLOCK *****
 | 
				
			||||||
# This file is part of InDefero, an open source project management application.
 | 
					# This file is part of InDefero, an open source project management application.
 | 
				
			||||||
# Copyright (C) 2008 Céondo Ltd and contributors.
 | 
					# Copyright (C) 2008-2011 Céondo Ltd and contributors.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# InDefero is free software; you can redistribute it and/or modify
 | 
					# InDefero is free software; you can redistribute it and/or modify
 | 
				
			||||||
# it under the terms of the GNU General Public License as published by
 | 
					# it under the terms of the GNU General Public License as published by
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,7 +3,7 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
# ***** BEGIN LICENSE BLOCK *****
 | 
					# ***** BEGIN LICENSE BLOCK *****
 | 
				
			||||||
# This file is part of InDefero, an open source project management application.
 | 
					# This file is part of InDefero, an open source project management application.
 | 
				
			||||||
# Copyright (C) 2008 Céondo Ltd and contributors.
 | 
					# Copyright (C) 2008-2011 Céondo Ltd and contributors.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# InDefero is free software; you can redistribute it and/or modify
 | 
					# InDefero is free software; you can redistribute it and/or modify
 | 
				
			||||||
# it under the terms of the GNU General Public License as published by
 | 
					# it under the terms of the GNU General Public License as published by
 | 
				
			||||||
@@ -169,6 +169,24 @@ class IDF_Issue extends Pluf_Model
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    function getGroupedRelatedIssues($opts = array(), $idsOnly = false)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $rels = $this->get_related_issues_list(array_merge($opts, array(
 | 
				
			||||||
 | 
					               'view' => 'with_other_issue',
 | 
				
			||||||
 | 
					        )));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $res = array();
 | 
				
			||||||
 | 
					        foreach ($rels as $rel) {
 | 
				
			||||||
 | 
					            $verb = $rel->verb;
 | 
				
			||||||
 | 
					            if (!array_key_exists($verb, $res)) {
 | 
				
			||||||
 | 
					                $res[$verb] = array();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            $res[$verb][] = $idsOnly ? $rel->other_issue : $rel;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $res;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Returns an HTML fragment used to display this issue in the
 | 
					     * Returns an HTML fragment used to display this issue in the
 | 
				
			||||||
     * timeline.
 | 
					     * timeline.
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,7 +3,7 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
# ***** BEGIN LICENSE BLOCK *****
 | 
					# ***** BEGIN LICENSE BLOCK *****
 | 
				
			||||||
# This file is part of InDefero, an open source project management application.
 | 
					# This file is part of InDefero, an open source project management application.
 | 
				
			||||||
# Copyright (C) 2008 Céondo Ltd and contributors.
 | 
					# Copyright (C) 2008-2011 Céondo Ltd and contributors.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# InDefero is free software; you can redistribute it and/or modify
 | 
					# InDefero is free software; you can redistribute it and/or modify
 | 
				
			||||||
# it under the terms of the GNU General Public License as published by
 | 
					# it under the terms of the GNU General Public License as published by
 | 
				
			||||||
@@ -155,10 +155,19 @@ class IDF_IssueComment extends Pluf_Model
 | 
				
			|||||||
                    $out .= __('Owner:'); break;
 | 
					                    $out .= __('Owner:'); break;
 | 
				
			||||||
                case 'lb':
 | 
					                case 'lb':
 | 
				
			||||||
                    $out .= __('Labels:'); break;
 | 
					                    $out .= __('Labels:'); break;
 | 
				
			||||||
 | 
					                case 'rel':
 | 
				
			||||||
 | 
					                    $out .= __('Relations:'); break;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                $out .= '</strong> ';
 | 
					                $out .= '</strong> ';
 | 
				
			||||||
                if ($w == 'lb') {
 | 
					                if ($w == 'lb' || $w == 'rel') {
 | 
				
			||||||
                    $out .= Pluf_esc(implode(', ', $v));
 | 
					                    foreach ($v as $t => $ls) {
 | 
				
			||||||
 | 
					                        foreach ($ls as $l) {
 | 
				
			||||||
 | 
					                            if ($t == 'rem') $out .= '<s>';
 | 
				
			||||||
 | 
					                            $out .= Pluf_esc($l);
 | 
				
			||||||
 | 
					                            if ($t == 'rem') $out .= '</s>';
 | 
				
			||||||
 | 
					                            $out .= ' ';
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
                } else {
 | 
					                } else {
 | 
				
			||||||
                    $out .= Pluf_esc($v);
 | 
					                    $out .= Pluf_esc($v);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,7 +3,7 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
# ***** BEGIN LICENSE BLOCK *****
 | 
					# ***** BEGIN LICENSE BLOCK *****
 | 
				
			||||||
# This file is part of InDefero, an open source project management application.
 | 
					# This file is part of InDefero, an open source project management application.
 | 
				
			||||||
# Copyright (C) 2008 Céondo Ltd and contributors.
 | 
					# Copyright (C) 2008-2011 Céondo Ltd and contributors.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# InDefero is free software; you can redistribute it and/or modify
 | 
					# InDefero is free software; you can redistribute it and/or modify
 | 
				
			||||||
# it under the terms of the GNU General Public License as published by
 | 
					# it under the terms of the GNU General Public License as published by
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										100
									
								
								src/IDF/IssueRelation.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										100
									
								
								src/IDF/IssueRelation.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,100 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					/* -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					# ***** BEGIN LICENSE BLOCK *****
 | 
				
			||||||
 | 
					# This file is part of InDefero, an open source project management application.
 | 
				
			||||||
 | 
					# Copyright (C) 2008-2011 Céondo Ltd and contributors.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# InDefero is free software; you can redistribute it and/or modify
 | 
				
			||||||
 | 
					# it under the terms of the GNU General Public License as published by
 | 
				
			||||||
 | 
					# the Free Software Foundation; either version 2 of the License, or
 | 
				
			||||||
 | 
					# (at your option) any later version.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# InDefero is distributed in the hope that it will be useful,
 | 
				
			||||||
 | 
					# but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
				
			||||||
 | 
					# GNU General Public License for more details.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# You should have received a copy of the GNU General Public License
 | 
				
			||||||
 | 
					# along with this program; if not, write to the Free Software
 | 
				
			||||||
 | 
					# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# ***** END LICENSE BLOCK ***** */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * A relation of one issue to another
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					class IDF_IssueRelation extends Pluf_Model
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public $_model = __CLASS__;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    function init()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $this->_a['table'] = 'idf_issuerelations';
 | 
				
			||||||
 | 
					        $this->_a['model'] = __CLASS__;
 | 
				
			||||||
 | 
					        $this->_a['cols'] = array(
 | 
				
			||||||
 | 
					                             // It is mandatory to have an "id" column.
 | 
				
			||||||
 | 
					                            'id' =>
 | 
				
			||||||
 | 
					                            array(
 | 
				
			||||||
 | 
					                                  'type' => 'Pluf_DB_Field_Sequence',
 | 
				
			||||||
 | 
					                                  'blank' => true,
 | 
				
			||||||
 | 
					                                  ),
 | 
				
			||||||
 | 
					                            'issue' =>
 | 
				
			||||||
 | 
					                            array(
 | 
				
			||||||
 | 
					                                  'type' => 'Pluf_DB_Field_Foreignkey',
 | 
				
			||||||
 | 
					                                  'model' => 'IDF_Issue',
 | 
				
			||||||
 | 
					                                  'blank' => false,
 | 
				
			||||||
 | 
					                                  'verbose' => __('issue'),
 | 
				
			||||||
 | 
					                                  'relate_name' => 'related_issues',
 | 
				
			||||||
 | 
					                                  ),
 | 
				
			||||||
 | 
					                            'verb' =>
 | 
				
			||||||
 | 
					                            array(
 | 
				
			||||||
 | 
					                                  'type' => 'Pluf_DB_Field_Text',
 | 
				
			||||||
 | 
					                                  'blank' => false,
 | 
				
			||||||
 | 
					                                  'verbose' => __('verb'),
 | 
				
			||||||
 | 
					                                  ),
 | 
				
			||||||
 | 
					                            'other_issue' =>
 | 
				
			||||||
 | 
					                            array(
 | 
				
			||||||
 | 
					                                  'type' => 'Pluf_DB_Field_Foreignkey',
 | 
				
			||||||
 | 
					                                  'model' => 'IDF_Issue',
 | 
				
			||||||
 | 
					                                  'blank' => false,
 | 
				
			||||||
 | 
					                                  'verbose' => __('other issue'),
 | 
				
			||||||
 | 
					                                  'relate_name' => 'related_other_issues',
 | 
				
			||||||
 | 
					                                  ),
 | 
				
			||||||
 | 
					                            'submitter' =>
 | 
				
			||||||
 | 
					                            array(
 | 
				
			||||||
 | 
					                                  'type' => 'Pluf_DB_Field_Foreignkey',
 | 
				
			||||||
 | 
					                                  'model' => 'Pluf_User',
 | 
				
			||||||
 | 
					                                  'blank' => false,
 | 
				
			||||||
 | 
					                                  'verbose' => __('submitter'),
 | 
				
			||||||
 | 
					                                   ),
 | 
				
			||||||
 | 
					                            'creation_dtime' =>
 | 
				
			||||||
 | 
					                            array(
 | 
				
			||||||
 | 
					                                  'type' => 'Pluf_DB_Field_Datetime',
 | 
				
			||||||
 | 
					                                  'blank' => true,
 | 
				
			||||||
 | 
					                                  'verbose' => __('creation date'),
 | 
				
			||||||
 | 
					                                  ),
 | 
				
			||||||
 | 
					                            );
 | 
				
			||||||
 | 
					        $this->_a['idx'] = array(
 | 
				
			||||||
 | 
					                            'creation_dtime_idx' =>
 | 
				
			||||||
 | 
					                            array(
 | 
				
			||||||
 | 
					                                  'col' => 'creation_dtime',
 | 
				
			||||||
 | 
					                                  'type' => 'normal',
 | 
				
			||||||
 | 
					                                  ),
 | 
				
			||||||
 | 
					                            );
 | 
				
			||||||
 | 
					        $issuetbl = $this->_con->pfx.'idf_issues';
 | 
				
			||||||
 | 
					        $this->_a['views'] = array(
 | 
				
			||||||
 | 
					            'with_other_issue' => array(
 | 
				
			||||||
 | 
					                'join' => 'INNER JOIN '.$issuetbl.' ON other_issue='.$issuetbl.'.id',
 | 
				
			||||||
 | 
					                'select' => $this->getSelect().', summary',
 | 
				
			||||||
 | 
					                'props' => array('summary' => 'other_summary'),
 | 
				
			||||||
 | 
					        ));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    function preSave($create=false)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if ($this->id == '') {
 | 
				
			||||||
 | 
					            $this->creation_dtime = gmdate('Y-m-d H:i:s');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -3,7 +3,7 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
# ***** BEGIN LICENSE BLOCK *****
 | 
					# ***** BEGIN LICENSE BLOCK *****
 | 
				
			||||||
# This file is part of InDefero, an open source project management application.
 | 
					# This file is part of InDefero, an open source project management application.
 | 
				
			||||||
# Copyright (C) 2008 Céondo Ltd and contributors.
 | 
					# Copyright (C) 2008-2011 Céondo Ltd and contributors.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# InDefero is free software; you can redistribute it and/or modify
 | 
					# InDefero is free software; you can redistribute it and/or modify
 | 
				
			||||||
# it under the terms of the GNU General Public License as published by
 | 
					# it under the terms of the GNU General Public License as published by
 | 
				
			||||||
@@ -80,7 +80,10 @@ class IDF_Key extends Pluf_Model
 | 
				
			|||||||
        if (preg_match('#^\[pubkey ([^\]]+)\]\s*(\S+)\s*\[end\]$#', $this->content, $m)) {
 | 
					        if (preg_match('#^\[pubkey ([^\]]+)\]\s*(\S+)\s*\[end\]$#', $this->content, $m)) {
 | 
				
			||||||
            return array('mtn', $m[1], $m[2]);
 | 
					            return array('mtn', $m[1], $m[2]);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        else if (preg_match('#^ssh\-[a-z]{3}\s(\S+)(?:\s(\S+))?$#', $this->content, $m)) {
 | 
					        else if (preg_match('#^ssh\-(?:dss|rsa)\s(\S+)(?:\s(.*))?$#', $this->content, $m)) {
 | 
				
			||||||
 | 
					            if (!isset($m[2])) {
 | 
				
			||||||
 | 
					                $m[2] = "";
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
            return array('ssh', $m[2], $m[1]);
 | 
					            return array('ssh', $m[2], $m[1]);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,7 +3,7 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
# ***** BEGIN LICENSE BLOCK *****
 | 
					# ***** BEGIN LICENSE BLOCK *****
 | 
				
			||||||
# This file is part of InDefero, an open source project management application.
 | 
					# This file is part of InDefero, an open source project management application.
 | 
				
			||||||
# Copyright (C) 2008 Céondo Ltd and contributors.
 | 
					# Copyright (C) 2008-2011 Céondo Ltd and contributors.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# InDefero is free software; you can redistribute it and/or modify
 | 
					# InDefero is free software; you can redistribute it and/or modify
 | 
				
			||||||
# it under the terms of the GNU General Public License as published by
 | 
					# it under the terms of the GNU General Public License as published by
 | 
				
			||||||
@@ -44,7 +44,7 @@ class IDF_Middleware
 | 
				
			|||||||
    function process_request(&$request)
 | 
					    function process_request(&$request)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $match = array();
 | 
					        $match = array();
 | 
				
			||||||
        if (preg_match('#^/(?:api/p|p)/([\-\w]+)/?#', $request->query, $match)) {
 | 
					        if (preg_match('#^/(?:api/p|p|r)/([\-\w]+)/?#', $request->query, $match)) {
 | 
				
			||||||
            try {
 | 
					            try {
 | 
				
			||||||
                $request->project = IDF_Project::getOr404($match[1]);
 | 
					                $request->project = IDF_Project::getOr404($match[1]);
 | 
				
			||||||
            } catch (Pluf_HTTP_Error404 $e) {
 | 
					            } catch (Pluf_HTTP_Error404 $e) {
 | 
				
			||||||
@@ -87,6 +87,7 @@ class IDF_Middleware
 | 
				
			|||||||
                              'markdown' => 'IDF_Template_Markdown',
 | 
					                              'markdown' => 'IDF_Template_Markdown',
 | 
				
			||||||
                              'showuser' => 'IDF_Template_ShowUser',
 | 
					                              'showuser' => 'IDF_Template_ShowUser',
 | 
				
			||||||
                              'ashowuser' => 'IDF_Template_AssignShowUser',
 | 
					                              'ashowuser' => 'IDF_Template_AssignShowUser',
 | 
				
			||||||
 | 
					                              'appversion' => 'IDF_Template_AppVersion',
 | 
				
			||||||
                                            ));
 | 
					                                            ));
 | 
				
			||||||
        $params['modifiers'] = array_merge($params['modifiers'],
 | 
					        $params['modifiers'] = array_merge($params['modifiers'],
 | 
				
			||||||
                                           array(
 | 
					                                           array(
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,7 +3,7 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
# ***** BEGIN LICENSE BLOCK *****
 | 
					# ***** BEGIN LICENSE BLOCK *****
 | 
				
			||||||
# This file is part of InDefero, an open source project management application.
 | 
					# This file is part of InDefero, an open source project management application.
 | 
				
			||||||
# Copyright (C) 2008 Céondo Ltd and contributors.
 | 
					# Copyright (C) 2008-2011 Céondo Ltd and contributors.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# InDefero is free software; you can redistribute it and/or modify
 | 
					# InDefero is free software; you can redistribute it and/or modify
 | 
				
			||||||
# it under the terms of the GNU General Public License as published by
 | 
					# it under the terms of the GNU General Public License as published by
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,7 +3,7 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
# ***** BEGIN LICENSE BLOCK *****
 | 
					# ***** BEGIN LICENSE BLOCK *****
 | 
				
			||||||
# This file is part of InDefero, an open source project management application.
 | 
					# This file is part of InDefero, an open source project management application.
 | 
				
			||||||
# Copyright (C) 2008 Céondo Ltd and contributors.
 | 
					# Copyright (C) 2008-2011 Céondo Ltd and contributors.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# InDefero is free software; you can redistribute it and/or modify
 | 
					# InDefero is free software; you can redistribute it and/or modify
 | 
				
			||||||
# it under the terms of the GNU General Public License as published by
 | 
					# it under the terms of the GNU General Public License as published by
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,7 +3,7 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
# ***** BEGIN LICENSE BLOCK *****
 | 
					# ***** BEGIN LICENSE BLOCK *****
 | 
				
			||||||
# This file is part of InDefero, an open source project management application.
 | 
					# This file is part of InDefero, an open source project management application.
 | 
				
			||||||
# Copyright (C) 2008 Céondo Ltd and contributors.
 | 
					# Copyright (C) 2008-2011 Céondo Ltd and contributors.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# InDefero is free software; you can redistribute it and/or modify
 | 
					# InDefero is free software; you can redistribute it and/or modify
 | 
				
			||||||
# it under the terms of the GNU General Public License as published by
 | 
					# it under the terms of the GNU General Public License as published by
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,7 +3,7 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
# ***** BEGIN LICENSE BLOCK *****
 | 
					# ***** BEGIN LICENSE BLOCK *****
 | 
				
			||||||
# This file is part of InDefero, an open source project management application.
 | 
					# This file is part of InDefero, an open source project management application.
 | 
				
			||||||
# Copyright (C) 2008 Céondo Ltd and contributors.
 | 
					# Copyright (C) 2008-2011 Céondo Ltd and contributors.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# InDefero is free software; you can redistribute it and/or modify
 | 
					# InDefero is free software; you can redistribute it and/or modify
 | 
				
			||||||
# it under the terms of the GNU General Public License as published by
 | 
					# it under the terms of the GNU General Public License as published by
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,7 +3,7 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
# ***** BEGIN LICENSE BLOCK *****
 | 
					# ***** BEGIN LICENSE BLOCK *****
 | 
				
			||||||
# This file is part of InDefero, an open source project management application.
 | 
					# This file is part of InDefero, an open source project management application.
 | 
				
			||||||
# Copyright (C) 2008 Céondo Ltd and contributors.
 | 
					# Copyright (C) 2008-2011 Céondo Ltd and contributors.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# InDefero is free software; you can redistribute it and/or modify
 | 
					# InDefero is free software; you can redistribute it and/or modify
 | 
				
			||||||
# it under the terms of the GNU General Public License as published by
 | 
					# it under the terms of the GNU General Public License as published by
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,7 +3,7 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
# ***** BEGIN LICENSE BLOCK *****
 | 
					# ***** BEGIN LICENSE BLOCK *****
 | 
				
			||||||
# This file is part of InDefero, an open source project management application.
 | 
					# This file is part of InDefero, an open source project management application.
 | 
				
			||||||
# Copyright (C) 2008 Céondo Ltd and contributors.
 | 
					# Copyright (C) 2008-2011 Céondo Ltd and contributors.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# InDefero is free software; you can redistribute it and/or modify
 | 
					# InDefero is free software; you can redistribute it and/or modify
 | 
				
			||||||
# it under the terms of the GNU General Public License as published by
 | 
					# it under the terms of the GNU General Public License as published by
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										43
									
								
								src/IDF/Migrations/16AddUserMail.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								src/IDF/Migrations/16AddUserMail.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,43 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					/* -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					# ***** BEGIN LICENSE BLOCK *****
 | 
				
			||||||
 | 
					# This file is part of InDefero, an open source project management application.
 | 
				
			||||||
 | 
					# Copyright (C) 2008-2011 Céondo Ltd and contributors.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# InDefero is free software; you can redistribute it and/or modify
 | 
				
			||||||
 | 
					# it under the terms of the GNU General Public License as published by
 | 
				
			||||||
 | 
					# the Free Software Foundation; either version 2 of the License, or
 | 
				
			||||||
 | 
					# (at your option) any later version.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# InDefero is distributed in the hope that it will be useful,
 | 
				
			||||||
 | 
					# but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
				
			||||||
 | 
					# GNU General Public License for more details.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# You should have received a copy of the GNU General Public License
 | 
				
			||||||
 | 
					# along with this program; if not, write to the Free Software
 | 
				
			||||||
 | 
					# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# ***** END LICENSE BLOCK ***** */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Add the new IDF_Gconf model.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function IDF_Migrations_16AddUserMail_up($params=null)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    $db = Pluf::db();
 | 
				
			||||||
 | 
					    $schema = new Pluf_DB_Schema($db);
 | 
				
			||||||
 | 
					    $schema->model = new IDF_EmailAddress();
 | 
				
			||||||
 | 
					    $schema->createTables();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function IDF_Migrations_16AddUserMail_down($params=null)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    $db = Pluf::db();
 | 
				
			||||||
 | 
					    $schema = new Pluf_DB_Schema($db);
 | 
				
			||||||
 | 
					    $schema->model = new IDF_EmailAddress();
 | 
				
			||||||
 | 
					    $schema->dropTables();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										90
									
								
								src/IDF/Migrations/17AddIssueRelations.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										90
									
								
								src/IDF/Migrations/17AddIssueRelations.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,90 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					/* -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					# ***** BEGIN LICENSE BLOCK *****
 | 
				
			||||||
 | 
					# This file is part of InDefero, an open source project management application.
 | 
				
			||||||
 | 
					# Copyright (C) 2008-2011 Céondo Ltd and contributors.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# InDefero is free software; you can redistribute it and/or modify
 | 
				
			||||||
 | 
					# it under the terms of the GNU General Public License as published by
 | 
				
			||||||
 | 
					# the Free Software Foundation; either version 2 of the License, or
 | 
				
			||||||
 | 
					# (at your option) any later version.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# InDefero is distributed in the hope that it will be useful,
 | 
				
			||||||
 | 
					# but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
				
			||||||
 | 
					# GNU General Public License for more details.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# You should have received a copy of the GNU General Public License
 | 
				
			||||||
 | 
					# along with this program; if not, write to the Free Software
 | 
				
			||||||
 | 
					# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# ***** END LICENSE BLOCK ***** */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Add the new IDF_IssueRelation model.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function IDF_Migrations_17AddIssueRelations_up($params=null)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    $db = Pluf::db();
 | 
				
			||||||
 | 
					    $schema = new Pluf_DB_Schema($db);
 | 
				
			||||||
 | 
					    $schema->model = new IDF_IssueRelation();
 | 
				
			||||||
 | 
					    $schema->createTables();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // change the serialization format for added / removed labels in IDF_IssueComment
 | 
				
			||||||
 | 
					    $comments = Pluf::factory('IDF_IssueComment')->getList();
 | 
				
			||||||
 | 
					    foreach ($comments as $comment) {
 | 
				
			||||||
 | 
					        if (!isset($comment->changes['lb'])) continue;
 | 
				
			||||||
 | 
					        $changes = $comment->changes;
 | 
				
			||||||
 | 
					        $adds = $removals = array();
 | 
				
			||||||
 | 
					        foreach ($comment->changes['lb'] as $lb) {
 | 
				
			||||||
 | 
					            if (substr($lb, 0, 1) == '-')
 | 
				
			||||||
 | 
					                $removals[] = substr($lb, 1);
 | 
				
			||||||
 | 
					            else
 | 
				
			||||||
 | 
					                $adds[] = $lb;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        $changes['lb'] = array();
 | 
				
			||||||
 | 
					        if (count($adds) > 0)
 | 
				
			||||||
 | 
					            $changes['lb']['add'] = $adds;
 | 
				
			||||||
 | 
					        if (count($removals) > 0)
 | 
				
			||||||
 | 
					            $changes['lb']['rem'] = $removals;
 | 
				
			||||||
 | 
					        $comment->changes = $changes;
 | 
				
			||||||
 | 
					        $comment->update();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function IDF_Migrations_17AddIssueRelations_down($params=null)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    $db = Pluf::db();
 | 
				
			||||||
 | 
					    $schema = new Pluf_DB_Schema($db);
 | 
				
			||||||
 | 
					    $schema->model = new IDF_IssueRelation();
 | 
				
			||||||
 | 
					    $schema->dropTables();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // change the serialization format for added / removed labels in IDF_IssueComment
 | 
				
			||||||
 | 
					    $comments = Pluf::factory('IDF_IssueComment')->getList();
 | 
				
			||||||
 | 
					    foreach ($comments as $comment) {
 | 
				
			||||||
 | 
					        $changes = $comment->changes;
 | 
				
			||||||
 | 
					        if (empty($changes))
 | 
				
			||||||
 | 
					            continue;
 | 
				
			||||||
 | 
					        if (isset($changes['lb'])) {
 | 
				
			||||||
 | 
					            $labels = array();
 | 
				
			||||||
 | 
					            foreach ($changes['lb'] as $type => $lbs) {
 | 
				
			||||||
 | 
					                if (!is_array($lbs)) {
 | 
				
			||||||
 | 
					                    $labels[] = $lbs;
 | 
				
			||||||
 | 
					                    continue;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                foreach ($lbs as $lb) {
 | 
				
			||||||
 | 
					                    $labels[] = ($type == 'rem' ? '-' : '') . $lb;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            $changes['lb'] = $labels;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        // while we're at it, remove any 'rel' changes
 | 
				
			||||||
 | 
					        unset($changes['rel']);
 | 
				
			||||||
 | 
					        $comment->changes = $changes;
 | 
				
			||||||
 | 
					        $comment->update();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										63
									
								
								src/IDF/Migrations/18DownloadMD5.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								src/IDF/Migrations/18DownloadMD5.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,63 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					/* -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					# ***** BEGIN LICENSE BLOCK *****
 | 
				
			||||||
 | 
					# This file is part of InDefero, an open source project management application.
 | 
				
			||||||
 | 
					# Copyright (C) 2008-2011 Céondo Ltd and contributors.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# InDefero is free software; you can redistribute it and/or modify
 | 
				
			||||||
 | 
					# it under the terms of the GNU General Public License as published by
 | 
				
			||||||
 | 
					# the Free Software Foundation; either version 2 of the License, or
 | 
				
			||||||
 | 
					# (at your option) any later version.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# InDefero is distributed in the hope that it will be useful,
 | 
				
			||||||
 | 
					# but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
				
			||||||
 | 
					# GNU General Public License for more details.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# You should have received a copy of the GNU General Public License
 | 
				
			||||||
 | 
					# along with this program; if not, write to the Free Software
 | 
				
			||||||
 | 
					# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# ***** END LICENSE BLOCK ***** */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Add the md5 column for the download model.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function IDF_Migrations_18DownloadMD5_up($params=null)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    // Add the row
 | 
				
			||||||
 | 
					    $table = Pluf::factory('IDF_Upload')->getSqlTable();
 | 
				
			||||||
 | 
					    $sql = array();
 | 
				
			||||||
 | 
					    $sql['PostgreSQL'] = 'ALTER TABLE '.$table.' ADD COLUMN "md5" VARCHAR(32) DEFAULT \'\'';
 | 
				
			||||||
 | 
					    $sql['MySQL'] = 'ALTER TABLE '.$table.' ADD COLUMN `md5` VARCHAR(32) DEFAULT \'\'';
 | 
				
			||||||
 | 
					    $db = Pluf::db();
 | 
				
			||||||
 | 
					    $engine = Pluf::f('db_engine');
 | 
				
			||||||
 | 
					    if (!isset($sql[$engine])) {
 | 
				
			||||||
 | 
					        throw new Exception('SQLite complex migration not supported.');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    $db->execute($sql[$engine]);
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    // Process md5 of already uploaded file
 | 
				
			||||||
 | 
					    $files = Pluf::factory('IDF_Upload')->getList();
 | 
				
			||||||
 | 
					    foreach ($files as $f) {
 | 
				
			||||||
 | 
					        $f->md5 = md5_file (Pluf::f('upload_path') . '/' . $f->get_project()->shortname . '/files/' . $f->file);
 | 
				
			||||||
 | 
					        $f->update();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function IDF_Migrations_18DownloadMD5_down($params=null)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    // Remove the row
 | 
				
			||||||
 | 
					    $table = Pluf::factory('IDF_Upload')->getSqlTable();
 | 
				
			||||||
 | 
					    $sql = array();
 | 
				
			||||||
 | 
					    $sql['PostgreSQL'] = 'ALTER TABLE '.$table.' DROP COLUMN "md5"';
 | 
				
			||||||
 | 
					    $sql['MySQL'] = 'ALTER TABLE '.$table.' DROP COLUMN `md5`';
 | 
				
			||||||
 | 
					    $db = Pluf::db();
 | 
				
			||||||
 | 
					    $engine = Pluf::f('db_engine');
 | 
				
			||||||
 | 
					    if (!isset($sql[$engine])) {
 | 
				
			||||||
 | 
					        throw new Exception('SQLite complex migration not supported.');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    $db->execute($sql[$engine]);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -3,7 +3,7 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
# ***** BEGIN LICENSE BLOCK *****
 | 
					# ***** BEGIN LICENSE BLOCK *****
 | 
				
			||||||
# This file is part of InDefero, an open source project management application.
 | 
					# This file is part of InDefero, an open source project management application.
 | 
				
			||||||
# Copyright (C) 2008 Céondo Ltd and contributors.
 | 
					# Copyright (C) 2008-2011 Céondo Ltd and contributors.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# InDefero is free software; you can redistribute it and/or modify
 | 
					# InDefero is free software; you can redistribute it and/or modify
 | 
				
			||||||
# it under the terms of the GNU General Public License as published by
 | 
					# it under the terms of the GNU General Public License as published by
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,7 +3,7 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
# ***** BEGIN LICENSE BLOCK *****
 | 
					# ***** BEGIN LICENSE BLOCK *****
 | 
				
			||||||
# This file is part of InDefero, an open source project management application.
 | 
					# This file is part of InDefero, an open source project management application.
 | 
				
			||||||
# Copyright (C) 2008 Céondo Ltd and contributors.
 | 
					# Copyright (C) 2008-2011 Céondo Ltd and contributors.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# InDefero is free software; you can redistribute it and/or modify
 | 
					# InDefero is free software; you can redistribute it and/or modify
 | 
				
			||||||
# it under the terms of the GNU General Public License as published by
 | 
					# it under the terms of the GNU General Public License as published by
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,7 +3,7 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
# ***** BEGIN LICENSE BLOCK *****
 | 
					# ***** BEGIN LICENSE BLOCK *****
 | 
				
			||||||
# This file is part of InDefero, an open source project management application.
 | 
					# This file is part of InDefero, an open source project management application.
 | 
				
			||||||
# Copyright (C) 2008 Céondo Ltd and contributors.
 | 
					# Copyright (C) 2008-2011 Céondo Ltd and contributors.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# InDefero is free software; you can redistribute it and/or modify
 | 
					# InDefero is free software; you can redistribute it and/or modify
 | 
				
			||||||
# it under the terms of the GNU General Public License as published by
 | 
					# it under the terms of the GNU General Public License as published by
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,7 +3,7 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
# ***** BEGIN LICENSE BLOCK *****
 | 
					# ***** BEGIN LICENSE BLOCK *****
 | 
				
			||||||
# This file is part of InDefero, an open source project management application.
 | 
					# This file is part of InDefero, an open source project management application.
 | 
				
			||||||
# Copyright (C) 2008 Céondo Ltd and contributors.
 | 
					# Copyright (C) 2008-2011 Céondo Ltd and contributors.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# InDefero is free software; you can redistribute it and/or modify
 | 
					# InDefero is free software; you can redistribute it and/or modify
 | 
				
			||||||
# it under the terms of the GNU General Public License as published by
 | 
					# it under the terms of the GNU General Public License as published by
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,7 +3,7 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
# ***** BEGIN LICENSE BLOCK *****
 | 
					# ***** BEGIN LICENSE BLOCK *****
 | 
				
			||||||
# This file is part of InDefero, an open source project management application.
 | 
					# This file is part of InDefero, an open source project management application.
 | 
				
			||||||
# Copyright (C) 2008 Céondo Ltd and contributors.
 | 
					# Copyright (C) 2008-2011 Céondo Ltd and contributors.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# InDefero is free software; you can redistribute it and/or modify
 | 
					# InDefero is free software; you can redistribute it and/or modify
 | 
				
			||||||
# it under the terms of the GNU General Public License as published by
 | 
					# it under the terms of the GNU General Public License as published by
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,7 +3,7 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
# ***** BEGIN LICENSE BLOCK *****
 | 
					# ***** BEGIN LICENSE BLOCK *****
 | 
				
			||||||
# This file is part of InDefero, an open source project management application.
 | 
					# This file is part of InDefero, an open source project management application.
 | 
				
			||||||
# Copyright (C) 2008 Céondo Ltd and contributors.
 | 
					# Copyright (C) 2008-2011 Céondo Ltd and contributors.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# InDefero is free software; you can redistribute it and/or modify
 | 
					# InDefero is free software; you can redistribute it and/or modify
 | 
				
			||||||
# it under the terms of the GNU General Public License as published by
 | 
					# it under the terms of the GNU General Public License as published by
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,7 +3,7 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
# ***** BEGIN LICENSE BLOCK *****
 | 
					# ***** BEGIN LICENSE BLOCK *****
 | 
				
			||||||
# This file is part of InDefero, an open source project management application.
 | 
					# This file is part of InDefero, an open source project management application.
 | 
				
			||||||
# Copyright (C) 2008 Céondo Ltd and contributors.
 | 
					# Copyright (C) 2008-2011 Céondo Ltd and contributors.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# InDefero is free software; you can redistribute it and/or modify
 | 
					# InDefero is free software; you can redistribute it and/or modify
 | 
				
			||||||
# it under the terms of the GNU General Public License as published by
 | 
					# it under the terms of the GNU General Public License as published by
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,7 +3,7 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
# ***** BEGIN LICENSE BLOCK *****
 | 
					# ***** BEGIN LICENSE BLOCK *****
 | 
				
			||||||
# This file is part of InDefero, an open source project management application.
 | 
					# This file is part of InDefero, an open source project management application.
 | 
				
			||||||
# Copyright (C) 2008 Céondo Ltd and contributors.
 | 
					# Copyright (C) 2008-2011 Céondo Ltd and contributors.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# InDefero is free software; you can redistribute it and/or modify
 | 
					# InDefero is free software; you can redistribute it and/or modify
 | 
				
			||||||
# it under the terms of the GNU General Public License as published by
 | 
					# it under the terms of the GNU General Public License as published by
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,7 +3,7 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
# ***** BEGIN LICENSE BLOCK *****
 | 
					# ***** BEGIN LICENSE BLOCK *****
 | 
				
			||||||
# This file is part of InDefero, an open source project management application.
 | 
					# This file is part of InDefero, an open source project management application.
 | 
				
			||||||
# Copyright (C) 2008 Céondo Ltd and contributors.
 | 
					# Copyright (C) 2008-2011 Céondo Ltd and contributors.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# InDefero is free software; you can redistribute it and/or modify
 | 
					# InDefero is free software; you can redistribute it and/or modify
 | 
				
			||||||
# it under the terms of the GNU General Public License as published by
 | 
					# it under the terms of the GNU General Public License as published by
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,7 +3,7 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
# ***** BEGIN LICENSE BLOCK *****
 | 
					# ***** BEGIN LICENSE BLOCK *****
 | 
				
			||||||
# This file is part of InDefero, an open source project management application.
 | 
					# This file is part of InDefero, an open source project management application.
 | 
				
			||||||
# Copyright (C) 2008 Céondo Ltd and contributors.
 | 
					# Copyright (C) 2008-2011 Céondo Ltd and contributors.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# InDefero is free software; you can redistribute it and/or modify
 | 
					# InDefero is free software; you can redistribute it and/or modify
 | 
				
			||||||
# it under the terms of the GNU General Public License as published by
 | 
					# it under the terms of the GNU General Public License as published by
 | 
				
			||||||
@@ -53,6 +53,8 @@ function IDF_Migrations_Backup_run($folder, $name=null)
 | 
				
			|||||||
                    'IDF_Scm_Cache_Git',
 | 
					                    'IDF_Scm_Cache_Git',
 | 
				
			||||||
                    'IDF_Queue',
 | 
					                    'IDF_Queue',
 | 
				
			||||||
                    'IDF_Gconf',
 | 
					                    'IDF_Gconf',
 | 
				
			||||||
 | 
					                    'IDF_EmailAddress',
 | 
				
			||||||
 | 
					                    'IDF_IssueRelation',
 | 
				
			||||||
                    );
 | 
					                    );
 | 
				
			||||||
    $db = Pluf::db();
 | 
					    $db = Pluf::db();
 | 
				
			||||||
    // Now, for each table, we dump the content in json, this is a
 | 
					    // Now, for each table, we dump the content in json, this is a
 | 
				
			||||||
@@ -98,6 +100,8 @@ function IDF_Migrations_Backup_restore($folder, $name)
 | 
				
			|||||||
                    'IDF_Scm_Cache_Git',
 | 
					                    'IDF_Scm_Cache_Git',
 | 
				
			||||||
                    'IDF_Queue',
 | 
					                    'IDF_Queue',
 | 
				
			||||||
                    'IDF_Gconf',
 | 
					                    'IDF_Gconf',
 | 
				
			||||||
 | 
					                    'IDF_EmailAddress',
 | 
				
			||||||
 | 
					                    'IDF_IssueRelation',
 | 
				
			||||||
                    );
 | 
					                    );
 | 
				
			||||||
    $db = Pluf::db();
 | 
					    $db = Pluf::db();
 | 
				
			||||||
    $schema = new Pluf_DB_Schema($db);
 | 
					    $schema = new Pluf_DB_Schema($db);
 | 
				
			||||||
@@ -110,4 +114,4 @@ function IDF_Migrations_Backup_restore($folder, $name)
 | 
				
			|||||||
        Pluf_Test_Fixture::load($data, false);
 | 
					        Pluf_Test_Fixture::load($data, false);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return true;
 | 
					    return true;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,7 +3,7 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
# ***** BEGIN LICENSE BLOCK *****
 | 
					# ***** BEGIN LICENSE BLOCK *****
 | 
				
			||||||
# This file is part of InDefero, an open source project management application.
 | 
					# This file is part of InDefero, an open source project management application.
 | 
				
			||||||
# Copyright (C) 2008 Céondo Ltd and contributors.
 | 
					# Copyright (C) 2008-2011 Céondo Ltd and contributors.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# InDefero is free software; you can redistribute it and/or modify
 | 
					# InDefero is free software; you can redistribute it and/or modify
 | 
				
			||||||
# it under the terms of the GNU General Public License as published by
 | 
					# it under the terms of the GNU General Public License as published by
 | 
				
			||||||
@@ -50,6 +50,8 @@ function IDF_Migrations_Install_setup($params=null)
 | 
				
			|||||||
                    'IDF_Scm_Cache_Git',
 | 
					                    'IDF_Scm_Cache_Git',
 | 
				
			||||||
                    'IDF_Queue',
 | 
					                    'IDF_Queue',
 | 
				
			||||||
                    'IDF_Gconf',
 | 
					                    'IDF_Gconf',
 | 
				
			||||||
 | 
					                    'IDF_EmailAddress',
 | 
				
			||||||
 | 
					                    'IDF_IssueRelation',
 | 
				
			||||||
                    );
 | 
					                    );
 | 
				
			||||||
    $db = Pluf::db();
 | 
					    $db = Pluf::db();
 | 
				
			||||||
    $schema = new Pluf_DB_Schema($db);
 | 
					    $schema = new Pluf_DB_Schema($db);
 | 
				
			||||||
@@ -107,6 +109,8 @@ function IDF_Migrations_Install_teardown($params=null)
 | 
				
			|||||||
                    'IDF_Tag',
 | 
					                    'IDF_Tag',
 | 
				
			||||||
                    'IDF_Commit',
 | 
					                    'IDF_Commit',
 | 
				
			||||||
                    'IDF_Project',
 | 
					                    'IDF_Project',
 | 
				
			||||||
 | 
					                    'IDF_EmailAddress',
 | 
				
			||||||
 | 
					                    'IDF_IssueRelation',
 | 
				
			||||||
                    );
 | 
					                    );
 | 
				
			||||||
    $db = Pluf::db();
 | 
					    $db = Pluf::db();
 | 
				
			||||||
    $schema = new Pluf_DB_Schema($db);
 | 
					    $schema = new Pluf_DB_Schema($db);
 | 
				
			||||||
@@ -114,4 +118,4 @@ function IDF_Migrations_Install_teardown($params=null)
 | 
				
			|||||||
        $schema->model = new $model();
 | 
					        $schema->model = new $model();
 | 
				
			||||||
        $schema->dropTables();
 | 
					        $schema->dropTables();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,7 +3,7 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
# ***** BEGIN LICENSE BLOCK *****
 | 
					# ***** BEGIN LICENSE BLOCK *****
 | 
				
			||||||
# This file is part of InDefero, an open source project management application.
 | 
					# This file is part of InDefero, an open source project management application.
 | 
				
			||||||
# Copyright (C) 2008 Céondo Ltd and contributors.
 | 
					# Copyright (C) 2008-2011 Céondo Ltd and contributors.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# InDefero is free software; you can redistribute it and/or modify
 | 
					# InDefero is free software; you can redistribute it and/or modify
 | 
				
			||||||
# it under the terms of the GNU General Public License as published by
 | 
					# it under the terms of the GNU General Public License as published by
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,7 +3,7 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
# ***** BEGIN LICENSE BLOCK *****
 | 
					# ***** BEGIN LICENSE BLOCK *****
 | 
				
			||||||
# This file is part of InDefero, an open source project management application.
 | 
					# This file is part of InDefero, an open source project management application.
 | 
				
			||||||
# Copyright (C) 2008 Céondo Ltd and contributors.
 | 
					# Copyright (C) 2008-2011 Céondo Ltd and contributors.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# InDefero is free software; you can redistribute it and/or modify
 | 
					# InDefero is free software; you can redistribute it and/or modify
 | 
				
			||||||
# it under the terms of the GNU General Public License as published by
 | 
					# it under the terms of the GNU General Public License as published by
 | 
				
			||||||
@@ -59,6 +59,16 @@ class IDF_Plugin_SyncGit_Cron
 | 
				
			|||||||
                $out .= sprintf($template, $cmd, $key->login, $content)."\n";
 | 
					                $out .= sprintf($template, $cmd, $key->login, $content)."\n";
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					        $out = "# indefero start" . PHP_EOL . $out . "# indefero end" . PHP_EOL;
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        // We update only the part of the file between IDF_START / IDF_END comment
 | 
				
			||||||
 | 
					        $original_keys = file_get_contents($authorized_keys);
 | 
				
			||||||
 | 
					        if (strstr($original_keys, "# indefero start") && strstr($original_keys, "# indefero end")) {
 | 
				
			||||||
 | 
					            $out = preg_replace('/(#\sindefero\sstart).+(#\sindefero\send\s\s?)/isU', 
 | 
				
			||||||
 | 
					                                $out, $original_keys);
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					             $out .= $original_keys;   
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
        file_put_contents($authorized_keys, $out, LOCK_EX);
 | 
					        file_put_contents($authorized_keys, $out, LOCK_EX);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,7 +3,7 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
# ***** BEGIN LICENSE BLOCK *****
 | 
					# ***** BEGIN LICENSE BLOCK *****
 | 
				
			||||||
# This file is part of InDefero, an open source project management application.
 | 
					# This file is part of InDefero, an open source project management application.
 | 
				
			||||||
# Copyright (C) 2008 Céondo Ltd and contributors.
 | 
					# Copyright (C) 2008-2011 Céondo Ltd and contributors.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# InDefero is free software; you can redistribute it and/or modify
 | 
					# InDefero is free software; you can redistribute it and/or modify
 | 
				
			||||||
# it under the terms of the GNU General Public License as published by
 | 
					# it under the terms of the GNU General Public License as published by
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,7 +3,7 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
# ***** BEGIN LICENSE BLOCK *****
 | 
					# ***** BEGIN LICENSE BLOCK *****
 | 
				
			||||||
# This file is part of InDefero, an open source project management application.
 | 
					# This file is part of InDefero, an open source project management application.
 | 
				
			||||||
# Copyright (C) 2008 Céondo Ltd and contributors.
 | 
					# Copyright (C) 2008-2011 Céondo Ltd and contributors.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# InDefero is free software; you can redistribute it and/or modify
 | 
					# InDefero is free software; you can redistribute it and/or modify
 | 
				
			||||||
# it under the terms of the GNU General Public License as published by
 | 
					# it under the terms of the GNU General Public License as published by
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,7 +3,7 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
# ***** BEGIN LICENSE BLOCK *****
 | 
					# ***** BEGIN LICENSE BLOCK *****
 | 
				
			||||||
# This file is part of InDefero, an open source project management application.
 | 
					# This file is part of InDefero, an open source project management application.
 | 
				
			||||||
# Copyright (C) 2010 Céondo Ltd and contributors.
 | 
					# Copyright (C) 2008-2011 Céondo Ltd and contributors.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# InDefero is free software; you can redistribute it and/or modify
 | 
					# InDefero is free software; you can redistribute it and/or modify
 | 
				
			||||||
# it under the terms of the GNU General Public License as published by
 | 
					# it under the terms of the GNU General Public License as published by
 | 
				
			||||||
@@ -27,6 +27,18 @@
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
class IDF_Plugin_SyncMonotone
 | 
					class IDF_Plugin_SyncMonotone
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					    private $old_err_rep = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function __construct()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $this->old_err_rep = error_reporting(0);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function __destruct()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        error_reporting($this->old_err_rep);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Entry point of the plugin.
 | 
					     * Entry point of the plugin.
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
@@ -80,24 +92,33 @@ class IDF_Plugin_SyncMonotone
 | 
				
			|||||||
            return;
 | 
					            return;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // This guard cleans up on any kind of error, and here is how it works:
 | 
				
			||||||
 | 
					        // As long as the guard is not committed, it keeps a reference to
 | 
				
			||||||
 | 
					        // the given project. When the guard is destroyed and the reference
 | 
				
			||||||
 | 
					        // is still present, it deletes the object. The deletion indirectly
 | 
				
			||||||
 | 
					        // also calls into this plugin again, as the project delete hook
 | 
				
			||||||
 | 
					        // will be called, that removes any changes we've made during the
 | 
				
			||||||
 | 
					        // process.
 | 
				
			||||||
 | 
					        $projectGuard = new IDF_Plugin_SyncMonotone_ModelGuard($project);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $projecttempl = Pluf::f('mtn_repositories', false);
 | 
					        $projecttempl = Pluf::f('mtn_repositories', false);
 | 
				
			||||||
        if ($projecttempl === false) {
 | 
					        if ($projecttempl === false) {
 | 
				
			||||||
            throw new IDF_Scm_Exception(
 | 
					            $this->_diagnoseProblem(
 | 
				
			||||||
                 __('"mtn_repositories" must be defined in your configuration file.')
 | 
					                 __('"mtn_repositories" must be defined in your configuration file')
 | 
				
			||||||
            );
 | 
					            );
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $usher_config = Pluf::f('mtn_usher_conf', false);
 | 
					        $usher_config = Pluf::f('mtn_usher_conf', false);
 | 
				
			||||||
        if (!$usher_config || !is_writable($usher_config)) {
 | 
					        if (!$usher_config || !is_writable($usher_config)) {
 | 
				
			||||||
            throw new IDF_Scm_Exception(
 | 
					            $this->_diagnoseProblem(
 | 
				
			||||||
                 __('"mtn_usher_conf" does not exist or is not writable.')
 | 
					                 __('"mtn_usher_conf" does not exist or is not writable')
 | 
				
			||||||
            );
 | 
					            );
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $mtnpostpush = realpath(dirname(__FILE__) . '/../../../scripts/mtn-post-push');
 | 
					        $mtnpostpush = realpath(dirname(__FILE__) . '/../../../scripts/mtn-post-push');
 | 
				
			||||||
        if (!file_exists($mtnpostpush)) {
 | 
					        if (!file_exists($mtnpostpush)) {
 | 
				
			||||||
            throw new IDF_Scm_Exception(sprintf(
 | 
					            $this->_diagnoseProblem(sprintf(
 | 
				
			||||||
                __('Could not find mtn-post-push script "%s".'), $mtnpostpush
 | 
					                __('Could not find mtn-post-push script "%s"'), $mtnpostpush
 | 
				
			||||||
            ));
 | 
					            ));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -110,13 +131,12 @@ class IDF_Plugin_SyncMonotone
 | 
				
			|||||||
             'monotonerc.in',
 | 
					             'monotonerc.in',
 | 
				
			||||||
             'remote-automate-permissions.in',
 | 
					             'remote-automate-permissions.in',
 | 
				
			||||||
             'hooks.d/',
 | 
					             'hooks.d/',
 | 
				
			||||||
             // this is linked and not copied to be able to update
 | 
					 | 
				
			||||||
             // the list of read-only commands on upgrades
 | 
					 | 
				
			||||||
             'hooks.d/indefero_authorize_remote_automate.conf',
 | 
					 | 
				
			||||||
             'hooks.d/indefero_authorize_remote_automate.lua',
 | 
					             'hooks.d/indefero_authorize_remote_automate.lua',
 | 
				
			||||||
             'hooks.d/indefero_post_push.conf.in',
 | 
					             'hooks.d/indefero_post_push.conf.in',
 | 
				
			||||||
             'hooks.d/indefero_post_push.lua',
 | 
					             'hooks.d/indefero_post_push.lua',
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
 | 
					        // enable remote command execution of read-only commands
 | 
				
			||||||
 | 
					        // only for public projects
 | 
				
			||||||
        if (!$project->private) {
 | 
					        if (!$project->private) {
 | 
				
			||||||
            // this is linked and not copied to be able to update
 | 
					            // this is linked and not copied to be able to update
 | 
				
			||||||
            // the list of read-only commands on upgrades
 | 
					            // the list of read-only commands on upgrades
 | 
				
			||||||
@@ -131,8 +151,8 @@ class IDF_Plugin_SyncMonotone
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
        foreach ($confdir_contents as $content) {
 | 
					        foreach ($confdir_contents as $content) {
 | 
				
			||||||
            if (!file_exists($confdir.$content)) {
 | 
					            if (!file_exists($confdir.$content)) {
 | 
				
			||||||
                throw new IDF_Scm_Exception(sprintf(
 | 
					                $this->_diagnoseProblem(sprintf(
 | 
				
			||||||
                    __('The configuration file %s is missing.'), $content
 | 
					                    __('The configuration file "%s" is missing'), $content
 | 
				
			||||||
                ));
 | 
					                ));
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@@ -140,14 +160,15 @@ class IDF_Plugin_SyncMonotone
 | 
				
			|||||||
        $shortname = $project->shortname;
 | 
					        $shortname = $project->shortname;
 | 
				
			||||||
        $projectpath = sprintf($projecttempl, $shortname);
 | 
					        $projectpath = sprintf($projecttempl, $shortname);
 | 
				
			||||||
        if (file_exists($projectpath)) {
 | 
					        if (file_exists($projectpath)) {
 | 
				
			||||||
            throw new IDF_Scm_Exception(sprintf(
 | 
					            $this->_diagnoseProblem(sprintf(
 | 
				
			||||||
                __('The project path %s already exists.'), $projectpath
 | 
					                __('The project path "%s" already exists'), $projectpath
 | 
				
			||||||
            ));
 | 
					            ));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (!mkdir($projectpath)) {
 | 
					        if (!@mkdir($projectpath)) {
 | 
				
			||||||
            throw new IDF_Scm_Exception(sprintf(
 | 
					            $this->_diagnoseProblem(sprintf(
 | 
				
			||||||
                __('The project path %s could not be created.'), $projectpath
 | 
					                __('The project path "%s" could not be created'),
 | 
				
			||||||
 | 
					                $projectpath
 | 
				
			||||||
            ));
 | 
					            ));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -156,7 +177,7 @@ class IDF_Plugin_SyncMonotone
 | 
				
			|||||||
        //
 | 
					        //
 | 
				
			||||||
        $dbfile = $projectpath.'/database.mtn';
 | 
					        $dbfile = $projectpath.'/database.mtn';
 | 
				
			||||||
        $cmd = sprintf('db init -d %s', escapeshellarg($dbfile));
 | 
					        $cmd = sprintf('db init -d %s', escapeshellarg($dbfile));
 | 
				
			||||||
        self::_mtn_exec($cmd);
 | 
					        $this->_mtn_exec($cmd);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        //
 | 
					        //
 | 
				
			||||||
        // step 2) create a server key
 | 
					        // step 2) create a server key
 | 
				
			||||||
@@ -175,16 +196,17 @@ class IDF_Plugin_SyncMonotone
 | 
				
			|||||||
            escapeshellarg($projectpath),
 | 
					            escapeshellarg($projectpath),
 | 
				
			||||||
            escapeshellarg($serverkey)
 | 
					            escapeshellarg($serverkey)
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
        self::_mtn_exec($cmd);
 | 
					        $this->_mtn_exec($cmd);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        //
 | 
					        //
 | 
				
			||||||
        // step 3) create a client key, and save it in IDF
 | 
					        // step 3) create a client key, and save it in IDF
 | 
				
			||||||
        //
 | 
					        //
 | 
				
			||||||
        $keydir = Pluf::f('tmp_folder').'/mtn-client-keys';
 | 
					        $keydir = Pluf::f('tmp_folder').'/mtn-client-keys';
 | 
				
			||||||
        if (!file_exists($keydir)) {
 | 
					        if (!file_exists($keydir)) {
 | 
				
			||||||
            if (!mkdir($keydir)) {
 | 
					            if (!@mkdir($keydir)) {
 | 
				
			||||||
                throw new IDF_Scm_Exception(sprintf(
 | 
					                $this->_diagnoseProblem(sprintf(
 | 
				
			||||||
                    __('The key directory %s could not be created.'), $keydir
 | 
					                    __('The key directory "%s" could not be created'),
 | 
				
			||||||
 | 
					                    $keydir
 | 
				
			||||||
                ));
 | 
					                ));
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@@ -194,14 +216,14 @@ class IDF_Plugin_SyncMonotone
 | 
				
			|||||||
            escapeshellarg($keydir),
 | 
					            escapeshellarg($keydir),
 | 
				
			||||||
            escapeshellarg($clientkey_name)
 | 
					            escapeshellarg($clientkey_name)
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
        $keyinfo = self::_mtn_exec($cmd);
 | 
					        $keyinfo = $this->_mtn_exec($cmd);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $parsed_keyinfo = array();
 | 
					        $parsed_keyinfo = array();
 | 
				
			||||||
        try {
 | 
					        try {
 | 
				
			||||||
            $parsed_keyinfo = IDF_Scm_Monotone_BasicIO::parse($keyinfo);
 | 
					            $parsed_keyinfo = IDF_Scm_Monotone_BasicIO::parse($keyinfo);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        catch (Exception $e) {
 | 
					        catch (Exception $e) {
 | 
				
			||||||
            throw new IDF_Scm_Exception(sprintf(
 | 
					            $this->_diagnoseProblem(sprintf(
 | 
				
			||||||
                __('Could not parse key information: %s'), $e->getMessage()
 | 
					                __('Could not parse key information: %s'), $e->getMessage()
 | 
				
			||||||
            ));
 | 
					            ));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@@ -219,13 +241,13 @@ class IDF_Plugin_SyncMonotone
 | 
				
			|||||||
            escapeshellarg($keydir),
 | 
					            escapeshellarg($keydir),
 | 
				
			||||||
            escapeshellarg($clientkey_hash)
 | 
					            escapeshellarg($clientkey_hash)
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
        $clientkey_pubdata = self::_mtn_exec($cmd);
 | 
					        $clientkey_pubdata = $this->_mtn_exec($cmd);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $cmd = sprintf('au put_public_key --db=%s %s',
 | 
					        $cmd = sprintf('au put_public_key --db=%s %s',
 | 
				
			||||||
            escapeshellarg($dbfile),
 | 
					            escapeshellarg($dbfile),
 | 
				
			||||||
            escapeshellarg($clientkey_pubdata)
 | 
					            escapeshellarg($clientkey_pubdata)
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
        self::_mtn_exec($cmd);
 | 
					        $this->_mtn_exec($cmd);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        //
 | 
					        //
 | 
				
			||||||
        // step 4) setup the configuration
 | 
					        // step 4) setup the configuration
 | 
				
			||||||
@@ -238,18 +260,20 @@ class IDF_Plugin_SyncMonotone
 | 
				
			|||||||
        foreach ($confdir_contents as $content) {
 | 
					        foreach ($confdir_contents as $content) {
 | 
				
			||||||
            $filepath = $projectpath.'/'.$content;
 | 
					            $filepath = $projectpath.'/'.$content;
 | 
				
			||||||
            if (substr($content, -1) == '/') {
 | 
					            if (substr($content, -1) == '/') {
 | 
				
			||||||
                if (!mkdir($filepath)) {
 | 
					                if (!@mkdir($filepath)) {
 | 
				
			||||||
                    throw new IDF_Scm_Exception(sprintf(
 | 
					                    $this->_diagnoseProblem(sprintf(
 | 
				
			||||||
                        __('Could not create configuration directory "%s"'), $filepath
 | 
					                        __('Could not create configuration directory "%s"'),
 | 
				
			||||||
 | 
					                        $filepath
 | 
				
			||||||
                    ));
 | 
					                    ));
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                continue;
 | 
					                continue;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (substr($content, -3) != '.in') {
 | 
					            if (substr($content, -3) != '.in') {
 | 
				
			||||||
                if (!symlink($confdir.$content, $filepath)) {
 | 
					                if (!@symlink($confdir.$content, $filepath)) {
 | 
				
			||||||
                    IDF_Scm_Exception(sprintf(
 | 
					                    $this->_diagnoseProblem(sprintf(
 | 
				
			||||||
                        __('Could not create symlink "%s"'), $filepath
 | 
					                        __('Could not create symlink for configuration file "%s"'),
 | 
				
			||||||
 | 
					                        $filepath
 | 
				
			||||||
                    ));
 | 
					                    ));
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                continue;
 | 
					                continue;
 | 
				
			||||||
@@ -264,9 +288,10 @@ class IDF_Plugin_SyncMonotone
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            // remove the .in
 | 
					            // remove the .in
 | 
				
			||||||
            $filepath = substr($filepath, 0, -3);
 | 
					            $filepath = substr($filepath, 0, -3);
 | 
				
			||||||
            if (file_put_contents($filepath, $filecontents, LOCK_EX) === false) {
 | 
					            if (@file_put_contents($filepath, $filecontents, LOCK_EX) === false) {
 | 
				
			||||||
                throw new IDF_Scm_Exception(sprintf(
 | 
					                $this->_diagnoseProblem(sprintf(
 | 
				
			||||||
                    __('Could not write configuration file "%s"'), $filepath
 | 
					                    __('Could not write configuration file "%s"'),
 | 
				
			||||||
 | 
					                    $filepath
 | 
				
			||||||
                ));
 | 
					                ));
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@@ -280,7 +305,7 @@ class IDF_Plugin_SyncMonotone
 | 
				
			|||||||
            $parsed_config = IDF_Scm_Monotone_BasicIO::parse($usher_rc);
 | 
					            $parsed_config = IDF_Scm_Monotone_BasicIO::parse($usher_rc);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        catch (Exception $e) {
 | 
					        catch (Exception $e) {
 | 
				
			||||||
            throw new IDF_Scm_Exception(sprintf(
 | 
					            $this->_diagnoseProblem(sprintf(
 | 
				
			||||||
                __('Could not parse usher configuration in "%s": %s'),
 | 
					                __('Could not parse usher configuration in "%s": %s'),
 | 
				
			||||||
                $usher_config, $e->getMessage()
 | 
					                $usher_config, $e->getMessage()
 | 
				
			||||||
            ));
 | 
					            ));
 | 
				
			||||||
@@ -291,7 +316,7 @@ class IDF_Plugin_SyncMonotone
 | 
				
			|||||||
            foreach ($stanzas as $stanza_line) {
 | 
					            foreach ($stanzas as $stanza_line) {
 | 
				
			||||||
                if ($stanza_line['key'] == 'server' &&
 | 
					                if ($stanza_line['key'] == 'server' &&
 | 
				
			||||||
                    $stanza_line['values'][0] == $shortname) {
 | 
					                    $stanza_line['values'][0] == $shortname) {
 | 
				
			||||||
                    throw new IDF_Scm_Exception(sprintf(
 | 
					                    $this->_diagnoseProblem(sprintf(
 | 
				
			||||||
                        __('usher configuration already contains a server '.
 | 
					                        __('usher configuration already contains a server '.
 | 
				
			||||||
                           'entry named "%s"'),
 | 
					                           'entry named "%s"'),
 | 
				
			||||||
                        $shortname
 | 
					                        $shortname
 | 
				
			||||||
@@ -315,9 +340,10 @@ class IDF_Plugin_SyncMonotone
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        // FIXME: more sanity - what happens on failing writes? we do not
 | 
					        // FIXME: more sanity - what happens on failing writes? we do not
 | 
				
			||||||
        // have a backup copy of usher.conf around...
 | 
					        // have a backup copy of usher.conf around...
 | 
				
			||||||
        if (file_put_contents($usher_config, $usher_rc, LOCK_EX) === false) {
 | 
					        if (@file_put_contents($usher_config, $usher_rc, LOCK_EX) === false) {
 | 
				
			||||||
            throw new IDF_Scm_Exception(sprintf(
 | 
					            $this->_diagnoseProblem(sprintf(
 | 
				
			||||||
                __('Could not write usher configuration file "%s"'), $usher_config
 | 
					                __('Could not write usher configuration file "%s"'),
 | 
				
			||||||
 | 
					                $usher_config
 | 
				
			||||||
            ));
 | 
					            ));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -325,6 +351,9 @@ class IDF_Plugin_SyncMonotone
 | 
				
			|||||||
        // step 6) reload usher to pick up the new configuration
 | 
					        // step 6) reload usher to pick up the new configuration
 | 
				
			||||||
        //
 | 
					        //
 | 
				
			||||||
        IDF_Scm_Monotone_Usher::reload();
 | 
					        IDF_Scm_Monotone_Usher::reload();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // commit the guard, so the newly created project is not deleted
 | 
				
			||||||
 | 
					        $projectGuard->commit();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
@@ -345,8 +374,8 @@ class IDF_Plugin_SyncMonotone
 | 
				
			|||||||
        $mtn = IDF_Scm_Monotone::factory($project);
 | 
					        $mtn = IDF_Scm_Monotone::factory($project);
 | 
				
			||||||
        $stdio = $mtn->getStdio();
 | 
					        $stdio = $mtn->getStdio();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $projectpath = self::_get_project_path($project);
 | 
					        $projectpath = $this->_get_project_path($project);
 | 
				
			||||||
        $auth_ids    = self::_get_authorized_user_ids($project);
 | 
					        $auth_ids    = $this->_get_authorized_user_ids($project);
 | 
				
			||||||
        $key_ids     = array();
 | 
					        $key_ids     = array();
 | 
				
			||||||
        foreach ($auth_ids as $auth_id) {
 | 
					        foreach ($auth_ids as $auth_id) {
 | 
				
			||||||
            $sql = new Pluf_SQL('user=%s', array($auth_id));
 | 
					            $sql = new Pluf_SQL('user=%s', array($auth_id));
 | 
				
			||||||
@@ -361,9 +390,10 @@ class IDF_Plugin_SyncMonotone
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        $write_permissions = implode("\n", $key_ids);
 | 
					        $write_permissions = implode("\n", $key_ids);
 | 
				
			||||||
        $rcfile = $projectpath.'/write-permissions';
 | 
					        $rcfile = $projectpath.'/write-permissions';
 | 
				
			||||||
        if (file_put_contents($rcfile, $write_permissions, LOCK_EX) === false) {
 | 
					        if (@file_put_contents($rcfile, $write_permissions, LOCK_EX) === false) {
 | 
				
			||||||
            throw new IDF_Scm_Exception(sprintf(
 | 
					            $this->_diagnoseProblem(sprintf(
 | 
				
			||||||
                __('Could not write write-permissions file "%s"'), $rcfile
 | 
					                __('Could not write write-permissions file "%s"'),
 | 
				
			||||||
 | 
					                $rcfile
 | 
				
			||||||
            ));
 | 
					            ));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -382,11 +412,13 @@ class IDF_Plugin_SyncMonotone
 | 
				
			|||||||
                array('key' => 'allow', 'values' => array('*')),
 | 
					                array('key' => 'allow', 'values' => array('*')),
 | 
				
			||||||
            );
 | 
					            );
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $read_permissions = IDF_Scm_Monotone_BasicIO::compile(array($stanza));
 | 
					        $read_permissions = IDF_Scm_Monotone_BasicIO::compile(array($stanza));
 | 
				
			||||||
        $rcfile = $projectpath.'/read-permissions';
 | 
					        $rcfile = $projectpath.'/read-permissions';
 | 
				
			||||||
        if (file_put_contents($rcfile, $read_permissions, LOCK_EX) === false) {
 | 
					        if (@file_put_contents($rcfile, $read_permissions, LOCK_EX) === false) {
 | 
				
			||||||
            throw new IDF_Scm_Exception(sprintf(
 | 
					            $this->_diagnoseProblem(sprintf(
 | 
				
			||||||
                __('Could not write read-permissions file "%s"'), $rcfile
 | 
					                __('Could not write read-permissions file "%s"'),
 | 
				
			||||||
 | 
					                $rcfile
 | 
				
			||||||
            ));
 | 
					            ));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -401,16 +433,16 @@ class IDF_Plugin_SyncMonotone
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        $serverRestartRequired = false;
 | 
					        $serverRestartRequired = false;
 | 
				
			||||||
        if ($project->private && file_exists($projectfile) && is_link($projectfile)) {
 | 
					        if ($project->private && file_exists($projectfile) && is_link($projectfile)) {
 | 
				
			||||||
            if (!unlink($projectfile)) {
 | 
					            if (!@unlink($projectfile)) {
 | 
				
			||||||
                IDF_Scm_Exception(sprintf(
 | 
					                $this->_diagnoseProblem(sprintf(
 | 
				
			||||||
                    __('Could not remove symlink "%s"'), $projectfile
 | 
					                    __('Could not remove symlink "%s"'), $projectfile
 | 
				
			||||||
                ));
 | 
					                ));
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            $serverRestartRequired = true;
 | 
					            $serverRestartRequired = true;
 | 
				
			||||||
        } else
 | 
					        } else
 | 
				
			||||||
        if (!$project->private && !file_exists($projectfile)) {
 | 
					        if (!$project->private && !file_exists($projectfile)) {
 | 
				
			||||||
            if (!symlink($templatefile, $projectfile)) {
 | 
					            if (!@symlink($templatefile, $projectfile)) {
 | 
				
			||||||
                throw new IDF_Scm_Exception(sprintf(
 | 
					                $this->_diagnoseProblem(sprintf(
 | 
				
			||||||
                    __('Could not create symlink "%s"'), $projectfile
 | 
					                    __('Could not create symlink "%s"'), $projectfile
 | 
				
			||||||
                ));
 | 
					                ));
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
@@ -422,6 +454,9 @@ class IDF_Plugin_SyncMonotone
 | 
				
			|||||||
            // seems to be ignored when the server should be started
 | 
					            // seems to be ignored when the server should be started
 | 
				
			||||||
            // again immediately afterwards
 | 
					            // again immediately afterwards
 | 
				
			||||||
            IDF_Scm_Monotone_Usher::killServer($project->shortname);
 | 
					            IDF_Scm_Monotone_Usher::killServer($project->shortname);
 | 
				
			||||||
 | 
					            // give usher some time to cool down, otherwise it might hang
 | 
				
			||||||
 | 
					            // (see https://code.monotone.ca/p/contrib/issues/175/)
 | 
				
			||||||
 | 
					            sleep(2);
 | 
				
			||||||
            IDF_Scm_Monotone_Usher::startServer($project->shortname);
 | 
					            IDF_Scm_Monotone_Usher::startServer($project->shortname);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -443,8 +478,8 @@ class IDF_Plugin_SyncMonotone
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        $usher_config = Pluf::f('mtn_usher_conf', false);
 | 
					        $usher_config = Pluf::f('mtn_usher_conf', false);
 | 
				
			||||||
        if (!$usher_config || !is_writable($usher_config)) {
 | 
					        if (!$usher_config || !is_writable($usher_config)) {
 | 
				
			||||||
            throw new IDF_Scm_Exception(
 | 
					            $this->_diagnoseProblem(
 | 
				
			||||||
                 __('"mtn_usher_conf" does not exist or is not writable.')
 | 
					                 __('"mtn_usher_conf" does not exist or is not writable')
 | 
				
			||||||
            );
 | 
					            );
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -453,16 +488,16 @@ class IDF_Plugin_SyncMonotone
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        $projecttempl = Pluf::f('mtn_repositories', false);
 | 
					        $projecttempl = Pluf::f('mtn_repositories', false);
 | 
				
			||||||
        if ($projecttempl === false) {
 | 
					        if ($projecttempl === false) {
 | 
				
			||||||
            throw new IDF_Scm_Exception(
 | 
					            $this->_diagnoseProblem(
 | 
				
			||||||
                 __('"mtn_repositories" must be defined in your configuration file.')
 | 
					                 __('"mtn_repositories" must be defined in your configuration file')
 | 
				
			||||||
            );
 | 
					            );
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $projectpath = sprintf($projecttempl, $shortname);
 | 
					        $projectpath = sprintf($projecttempl, $shortname);
 | 
				
			||||||
        if (file_exists($projectpath)) {
 | 
					        if (file_exists($projectpath)) {
 | 
				
			||||||
            if (!self::_delete_recursive($projectpath)) {
 | 
					            if (!$this->_delete_recursive($projectpath)) {
 | 
				
			||||||
                throw new IDF_Scm_Exception(sprintf(
 | 
					                $this->_diagnoseProblem(sprintf(
 | 
				
			||||||
                    __('One or more paths underknees %s could not be deleted.'), $projectpath
 | 
					                    __('One or more paths underneath %s could not be deleted'), $projectpath
 | 
				
			||||||
                ));
 | 
					                ));
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@@ -473,8 +508,9 @@ class IDF_Plugin_SyncMonotone
 | 
				
			|||||||
        if ($keyname && $keyhash &&
 | 
					        if ($keyname && $keyhash &&
 | 
				
			||||||
            file_exists($keydir .'/'. $keyname . '.' . $keyhash)) {
 | 
					            file_exists($keydir .'/'. $keyname . '.' . $keyhash)) {
 | 
				
			||||||
            if (!@unlink($keydir .'/'. $keyname . '.' . $keyhash)) {
 | 
					            if (!@unlink($keydir .'/'. $keyname . '.' . $keyhash)) {
 | 
				
			||||||
                throw new IDF_Scm_Exception(sprintf(
 | 
					                $this->_diagnoseProblem(sprintf(
 | 
				
			||||||
                    __('Could not delete client private key %s'), $keyname
 | 
					                    __('Could not delete client private key "%s"'),
 | 
				
			||||||
 | 
					                    $keyname
 | 
				
			||||||
                ));
 | 
					                ));
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@@ -485,7 +521,7 @@ class IDF_Plugin_SyncMonotone
 | 
				
			|||||||
            $parsed_config = IDF_Scm_Monotone_BasicIO::parse($usher_rc);
 | 
					            $parsed_config = IDF_Scm_Monotone_BasicIO::parse($usher_rc);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        catch (Exception $e) {
 | 
					        catch (Exception $e) {
 | 
				
			||||||
            throw new IDF_Scm_Exception(sprintf(
 | 
					            $this->_diagnoseProblem(sprintf(
 | 
				
			||||||
                __('Could not parse usher configuration in "%s": %s'),
 | 
					                __('Could not parse usher configuration in "%s": %s'),
 | 
				
			||||||
                $usher_config, $e->getMessage()
 | 
					                $usher_config, $e->getMessage()
 | 
				
			||||||
            ));
 | 
					            ));
 | 
				
			||||||
@@ -505,9 +541,10 @@ class IDF_Plugin_SyncMonotone
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        // FIXME: more sanity - what happens on failing writes? we do not
 | 
					        // FIXME: more sanity - what happens on failing writes? we do not
 | 
				
			||||||
        // have a backup copy of usher.conf around...
 | 
					        // have a backup copy of usher.conf around...
 | 
				
			||||||
        if (file_put_contents($usher_config, $usher_rc, LOCK_EX) === false) {
 | 
					        if (@file_put_contents($usher_config, $usher_rc, LOCK_EX) === false) {
 | 
				
			||||||
            throw new IDF_Scm_Exception(sprintf(
 | 
					            $this->_diagnoseProblem(sprintf(
 | 
				
			||||||
                __('Could not write usher configuration file "%s"'), $usher_config
 | 
					                __('Could not write usher configuration file "%s"'),
 | 
				
			||||||
 | 
					                $usher_config
 | 
				
			||||||
            ));
 | 
					            ));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -528,6 +565,8 @@ class IDF_Plugin_SyncMonotone
 | 
				
			|||||||
            return;
 | 
					            return;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $keyGuard = new IDF_Plugin_SyncMonotone_ModelGuard($key);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        foreach (Pluf::factory('IDF_Project')->getList() as $project) {
 | 
					        foreach (Pluf::factory('IDF_Project')->getList() as $project) {
 | 
				
			||||||
            $conf = new IDF_Conf();
 | 
					            $conf = new IDF_Conf();
 | 
				
			||||||
            $conf->setProject($project);
 | 
					            $conf->setProject($project);
 | 
				
			||||||
@@ -535,8 +574,8 @@ class IDF_Plugin_SyncMonotone
 | 
				
			|||||||
            if ($scm != 'mtn')
 | 
					            if ($scm != 'mtn')
 | 
				
			||||||
                continue;
 | 
					                continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            $projectpath = self::_get_project_path($project);
 | 
					            $projectpath = $this->_get_project_path($project);
 | 
				
			||||||
            $auth_ids    = self::_get_authorized_user_ids($project);
 | 
					            $auth_ids    = $this->_get_authorized_user_ids($project);
 | 
				
			||||||
            if (!in_array($key->user, $auth_ids))
 | 
					            if (!in_array($key->user, $auth_ids))
 | 
				
			||||||
                continue;
 | 
					                continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -556,7 +595,7 @@ class IDF_Plugin_SyncMonotone
 | 
				
			|||||||
                    $parsed_read_perms = IDF_Scm_Monotone_BasicIO::parse($read_perms);
 | 
					                    $parsed_read_perms = IDF_Scm_Monotone_BasicIO::parse($read_perms);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                catch (Exception $e) {
 | 
					                catch (Exception $e) {
 | 
				
			||||||
                    throw new IDF_Scm_Exception(sprintf(
 | 
					                    $this->_diagnoseProblem(sprintf(
 | 
				
			||||||
                        __('Could not parse read-permissions for project "%s": %s'),
 | 
					                        __('Could not parse read-permissions for project "%s": %s'),
 | 
				
			||||||
                        $shortname, $e->getMessage()
 | 
					                        $shortname, $e->getMessage()
 | 
				
			||||||
                    ));
 | 
					                    ));
 | 
				
			||||||
@@ -598,10 +637,11 @@ class IDF_Plugin_SyncMonotone
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                $read_perms = IDF_Scm_Monotone_BasicIO::compile($parsed_read_perms);
 | 
					                $read_perms = IDF_Scm_Monotone_BasicIO::compile($parsed_read_perms);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                if (file_put_contents($projectpath.'/read-permissions',
 | 
					                if (@file_put_contents($projectpath.'/read-permissions',
 | 
				
			||||||
                                      $read_perms, LOCK_EX) === false) {
 | 
					                                      $read_perms, LOCK_EX) === false) {
 | 
				
			||||||
                    throw new IDF_Scm_Exception(sprintf(
 | 
					                    $this->_diagnoseProblem(sprintf(
 | 
				
			||||||
                        __('Could not write read-permissions for project "%s"'), $shortname
 | 
					                        __('Could not write read-permissions for project "%s"'),
 | 
				
			||||||
 | 
					                        $shortname
 | 
				
			||||||
                    ));
 | 
					                    ));
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
@@ -611,9 +651,9 @@ class IDF_Plugin_SyncMonotone
 | 
				
			|||||||
            if (!in_array('*', $lines) && !in_array($mtn_key_id, $lines)) {
 | 
					            if (!in_array('*', $lines) && !in_array($mtn_key_id, $lines)) {
 | 
				
			||||||
                $lines[] = $mtn_key_id;
 | 
					                $lines[] = $mtn_key_id;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            if (file_put_contents($projectpath.'/write-permissions',
 | 
					            if (@file_put_contents($projectpath.'/write-permissions',
 | 
				
			||||||
                                  implode("\n", $lines) . "\n", LOCK_EX) === false) {
 | 
					                                  implode("\n", $lines) . "\n", LOCK_EX) === false) {
 | 
				
			||||||
                throw new IDF_Scm_Exception(sprintf(
 | 
					                $this->_diagnoseProblem(sprintf(
 | 
				
			||||||
                    __('Could not write write-permissions file for project "%s"'),
 | 
					                    __('Could not write write-permissions file for project "%s"'),
 | 
				
			||||||
                    $shortname
 | 
					                    $shortname
 | 
				
			||||||
                ));
 | 
					                ));
 | 
				
			||||||
@@ -623,6 +663,8 @@ class IDF_Plugin_SyncMonotone
 | 
				
			|||||||
            $stdio = $mtn->getStdio();
 | 
					            $stdio = $mtn->getStdio();
 | 
				
			||||||
            $stdio->exec(array('put_public_key', $key->content));
 | 
					            $stdio->exec(array('put_public_key', $key->content));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $keyGuard->commit();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
@@ -651,8 +693,8 @@ class IDF_Plugin_SyncMonotone
 | 
				
			|||||||
            if ($scm != 'mtn')
 | 
					            if ($scm != 'mtn')
 | 
				
			||||||
                continue;
 | 
					                continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            $projectpath = self::_get_project_path($project);
 | 
					            $projectpath = $this->_get_project_path($project);
 | 
				
			||||||
            $auth_ids    = self::_get_authorized_user_ids($project);
 | 
					            $auth_ids    = $this->_get_authorized_user_ids($project);
 | 
				
			||||||
            if (!in_array($key->user, $auth_ids))
 | 
					            if (!in_array($key->user, $auth_ids))
 | 
				
			||||||
                continue;
 | 
					                continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -672,7 +714,7 @@ class IDF_Plugin_SyncMonotone
 | 
				
			|||||||
                    $parsed_read_perms = IDF_Scm_Monotone_BasicIO::parse($read_perms);
 | 
					                    $parsed_read_perms = IDF_Scm_Monotone_BasicIO::parse($read_perms);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                catch (Exception $e) {
 | 
					                catch (Exception $e) {
 | 
				
			||||||
                    throw new IDF_Scm_Exception(sprintf(
 | 
					                    $this->_diagnoseProblem(sprintf(
 | 
				
			||||||
                        __('Could not parse read-permissions for project "%s": %s'),
 | 
					                        __('Could not parse read-permissions for project "%s": %s'),
 | 
				
			||||||
                        $shortname, $e->getMessage()
 | 
					                        $shortname, $e->getMessage()
 | 
				
			||||||
                    ));
 | 
					                    ));
 | 
				
			||||||
@@ -693,10 +735,11 @@ class IDF_Plugin_SyncMonotone
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                $read_perms = IDF_Scm_Monotone_BasicIO::compile($parsed_read_perms);
 | 
					                $read_perms = IDF_Scm_Monotone_BasicIO::compile($parsed_read_perms);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                if (file_put_contents($projectpath.'/read-permissions',
 | 
					                if (@file_put_contents($projectpath.'/read-permissions',
 | 
				
			||||||
                                      $read_perms, LOCK_EX) === false) {
 | 
					                                      $read_perms, LOCK_EX) === false) {
 | 
				
			||||||
                    throw new IDF_Scm_Exception(sprintf(
 | 
					                    $this->_diagnoseProblem(sprintf(
 | 
				
			||||||
                        __('Could not write read-permissions for project "%s"'), $shortname
 | 
					                        __('Could not write read-permissions for project "%s"'),
 | 
				
			||||||
 | 
					                        $shortname
 | 
				
			||||||
                    ));
 | 
					                    ));
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
@@ -711,9 +754,9 @@ class IDF_Plugin_SyncMonotone
 | 
				
			|||||||
                    continue;
 | 
					                    continue;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            if (file_put_contents($projectpath.'/write-permissions',
 | 
					            if (@file_put_contents($projectpath.'/write-permissions',
 | 
				
			||||||
                                  implode("\n", $lines) . "\n", LOCK_EX) === false) {
 | 
					                                   implode("\n", $lines) . "\n", LOCK_EX) === false) {
 | 
				
			||||||
                throw new IDF_Scm_Exception(sprintf(
 | 
					                $this->_diagnoseProblem(sprintf(
 | 
				
			||||||
                    __('Could not write write-permissions file for project "%s"'),
 | 
					                    __('Could not write write-permissions file for project "%s"'),
 | 
				
			||||||
                    $shortname
 | 
					                    $shortname
 | 
				
			||||||
                ));
 | 
					                ));
 | 
				
			||||||
@@ -762,7 +805,43 @@ class IDF_Plugin_SyncMonotone
 | 
				
			|||||||
        ));
 | 
					        ));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private static function _get_authorized_user_ids($project)
 | 
					    private function _get_project_path($project)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $projecttempl = Pluf::f('mtn_repositories', false);
 | 
				
			||||||
 | 
					        if ($projecttempl === false) {
 | 
				
			||||||
 | 
					            $this->_diagnoseProblem(
 | 
				
			||||||
 | 
					                 __('"mtn_repositories" must be defined in your configuration file.')
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $projectpath = sprintf($projecttempl, $project->shortname);
 | 
				
			||||||
 | 
					        if (!file_exists($projectpath)) {
 | 
				
			||||||
 | 
					            $this->_diagnoseProblem(sprintf(
 | 
				
			||||||
 | 
					                __('The project path %s does not exists.'), $projectpath
 | 
				
			||||||
 | 
					            ));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return $projectpath;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private function _mtn_exec($cmd)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $fullcmd = sprintf('%s %s %s',
 | 
				
			||||||
 | 
					            Pluf::f('idf_exec_cmd_prefix', ''),
 | 
				
			||||||
 | 
					            Pluf::f('mtn_path', 'mtn'),
 | 
				
			||||||
 | 
					            $cmd
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $output = $return = null;
 | 
				
			||||||
 | 
					        exec($fullcmd, $output, $return);
 | 
				
			||||||
 | 
					        if ($return != 0) {
 | 
				
			||||||
 | 
					            $this->_diagnoseProblem(sprintf(
 | 
				
			||||||
 | 
					                __('The command "%s" could not be executed.'), $cmd
 | 
				
			||||||
 | 
					            ));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return implode("\n", $output);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private function _get_authorized_user_ids($project)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $mem = $project->getMembershipData();
 | 
					        $mem = $project->getMembershipData();
 | 
				
			||||||
        $members = array_merge((array)$mem['members'],
 | 
					        $members = array_merge((array)$mem['members'],
 | 
				
			||||||
@@ -775,43 +854,7 @@ class IDF_Plugin_SyncMonotone
 | 
				
			|||||||
        return $userids;
 | 
					        return $userids;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private static function _get_project_path($project)
 | 
					    private function _delete_recursive($path)
 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $projecttempl = Pluf::f('mtn_repositories', false);
 | 
					 | 
				
			||||||
        if ($projecttempl === false) {
 | 
					 | 
				
			||||||
            throw new IDF_Scm_Exception(
 | 
					 | 
				
			||||||
                 __('"mtn_repositories" must be defined in your configuration file.')
 | 
					 | 
				
			||||||
            );
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $projectpath = sprintf($projecttempl, $project->shortname);
 | 
					 | 
				
			||||||
        if (!file_exists($projectpath)) {
 | 
					 | 
				
			||||||
            throw new IDF_Scm_Exception(sprintf(
 | 
					 | 
				
			||||||
                __('The project path %s does not exists.'), $projectpath
 | 
					 | 
				
			||||||
            ));
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        return $projectpath;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    private static function _mtn_exec($cmd)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $fullcmd = sprintf('%s %s %s',
 | 
					 | 
				
			||||||
            Pluf::f('idf_exec_cmd_prefix', ''),
 | 
					 | 
				
			||||||
            Pluf::f('mtn_path', 'mtn'),
 | 
					 | 
				
			||||||
            $cmd
 | 
					 | 
				
			||||||
        );
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $output = $return = null;
 | 
					 | 
				
			||||||
        exec($fullcmd, $output, $return);
 | 
					 | 
				
			||||||
        if ($return != 0) {
 | 
					 | 
				
			||||||
            throw new IDF_Scm_Exception(sprintf(
 | 
					 | 
				
			||||||
                __('The command "%s" could not be executed.'), $cmd
 | 
					 | 
				
			||||||
            ));
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        return implode("\n", $output);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    private static function _delete_recursive($path)
 | 
					 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        if (is_file($path) || is_link($path)) {
 | 
					        if (is_file($path) || is_link($path)) {
 | 
				
			||||||
            return @unlink($path);
 | 
					            return @unlink($path);
 | 
				
			||||||
@@ -821,10 +864,48 @@ class IDF_Plugin_SyncMonotone
 | 
				
			|||||||
            $scan = glob(rtrim($path, '/') . '/*');
 | 
					            $scan = glob(rtrim($path, '/') . '/*');
 | 
				
			||||||
            $status = 0;
 | 
					            $status = 0;
 | 
				
			||||||
            foreach ($scan as $subpath) {
 | 
					            foreach ($scan as $subpath) {
 | 
				
			||||||
                $status |= self::_delete_recursive($subpath);
 | 
					                $status |= $this->_delete_recursive($subpath);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            $status |= rmdir($path);
 | 
					            $status |= @rmdir($path);
 | 
				
			||||||
            return $status;
 | 
					            return $status;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private function _diagnoseProblem($msg)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $system_err = error_get_last();
 | 
				
			||||||
 | 
					        if (!empty($system_err)) {
 | 
				
			||||||
 | 
					            $msg .= ': '.$system_err['message'];
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        error_reporting($this->old_err_rep);
 | 
				
			||||||
 | 
					        throw new IDF_Scm_Exception($msg);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * A simple helper class that deletes the model instance if
 | 
				
			||||||
 | 
					 * it is not committed
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					class IDF_Plugin_SyncMonotone_ModelGuard
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    private $model;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function __construct(Pluf_Model $m)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $this->model = $m;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function __destruct()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if ($this->model == null)
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
 | 
					        $this->model->delete();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function commit()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $this->model = null;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,6 @@
 | 
				
			|||||||
-- ***** BEGIN LICENSE BLOCK *****
 | 
					-- ***** BEGIN LICENSE BLOCK *****
 | 
				
			||||||
-- This file is part of InDefero, an open source project management application.
 | 
					-- This file is part of InDefero, an open source project management application.
 | 
				
			||||||
-- Copyright (C) 2011 Céondo Ltd and contributors.
 | 
					-- Copyright (C) 2008-2011 Céondo Ltd and contributors.
 | 
				
			||||||
-- Copyright (C) 2010 Thomas Keller <me@thomaskeller.biz>
 | 
					-- Copyright (C) 2010 Thomas Keller <me@thomaskeller.biz>
 | 
				
			||||||
--                    Richard Levitte <richard@levitte.org>
 | 
					--                    Richard Levitte <richard@levitte.org>
 | 
				
			||||||
--
 | 
					--
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,6 @@
 | 
				
			|||||||
-- ***** BEGIN LICENSE BLOCK *****
 | 
					-- ***** BEGIN LICENSE BLOCK *****
 | 
				
			||||||
-- This file is part of InDefero, an open source project management application.
 | 
					-- This file is part of InDefero, an open source project management application.
 | 
				
			||||||
-- Copyright (C) 2011 Céondo Ltd and contributors.
 | 
					-- Copyright (C) 2008-2011 Céondo Ltd and contributors.
 | 
				
			||||||
--
 | 
					--
 | 
				
			||||||
-- InDefero is free software; you can redistribute it and/or modify
 | 
					-- InDefero is free software; you can redistribute it and/or modify
 | 
				
			||||||
-- it under the terms of the GNU General Public License as published by
 | 
					-- it under the terms of the GNU General Public License as published by
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,6 @@
 | 
				
			|||||||
-- ***** BEGIN LICENSE BLOCK *****
 | 
					-- ***** BEGIN LICENSE BLOCK *****
 | 
				
			||||||
-- This file is part of InDefero, an open source project management application.
 | 
					-- This file is part of InDefero, an open source project management application.
 | 
				
			||||||
-- Copyright (C) 2011 Céondo Ltd and contributors.
 | 
					-- Copyright (C) 2008-2011 Céondo Ltd and contributors.
 | 
				
			||||||
--
 | 
					--
 | 
				
			||||||
-- InDefero is free software; you can redistribute it and/or modify
 | 
					-- InDefero is free software; you can redistribute it and/or modify
 | 
				
			||||||
-- it under the terms of the GNU General Public License as published by
 | 
					-- it under the terms of the GNU General Public License as published by
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,7 +3,7 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
# ***** BEGIN LICENSE BLOCK *****
 | 
					# ***** BEGIN LICENSE BLOCK *****
 | 
				
			||||||
# This file is part of InDefero, an open source project management application.
 | 
					# This file is part of InDefero, an open source project management application.
 | 
				
			||||||
# Copyright (C) 2008 Céondo Ltd and contributors.
 | 
					# Copyright (C) 2008-2011 Céondo Ltd and contributors.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# InDefero is free software; you can redistribute it and/or modify
 | 
					# InDefero is free software; you can redistribute it and/or modify
 | 
				
			||||||
# it under the terms of the GNU General Public License as published by
 | 
					# it under the terms of the GNU General Public License as published by
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,7 +3,7 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
# ***** BEGIN LICENSE BLOCK *****
 | 
					# ***** BEGIN LICENSE BLOCK *****
 | 
				
			||||||
# This file is part of InDefero, an open source project management application.
 | 
					# This file is part of InDefero, an open source project management application.
 | 
				
			||||||
# Copyright (C) 2008 Céondo Ltd and contributors.
 | 
					# Copyright (C) 2008-2011 Céondo Ltd and contributors.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# InDefero is free software; you can redistribute it and/or modify
 | 
					# InDefero is free software; you can redistribute it and/or modify
 | 
				
			||||||
# it under the terms of the GNU General Public License as published by
 | 
					# it under the terms of the GNU General Public License as published by
 | 
				
			||||||
@@ -190,7 +190,12 @@ class IDF_Precondition
 | 
				
			|||||||
            return true; // Again need authentication error
 | 
					            return true; // Again need authentication error
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        $request->user = $users[0];
 | 
					        $request->user = $users[0];
 | 
				
			||||||
        IDF_Middleware::setRights($request);
 | 
					        
 | 
				
			||||||
 | 
					        // Don't try to load projects rights access if we are not in one
 | 
				
			||||||
 | 
					        if ($request->query !== "/api/") {
 | 
				
			||||||
 | 
					            IDF_Middleware::setRights($request);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
        return true;
 | 
					        return true;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -256,4 +261,4 @@ class IDF_Precondition
 | 
				
			|||||||
        $encrypted = trim($cr->encrypt($user->id.':'.$project->id), '~');
 | 
					        $encrypted = trim($cr->encrypt($user->id.':'.$project->id), '~');
 | 
				
			||||||
        return substr(md5(Pluf::f('secret_key').$encrypted), 0, 2).$encrypted;
 | 
					        return substr(md5(Pluf::f('secret_key').$encrypted), 0, 2).$encrypted;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,7 +3,7 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
# ***** BEGIN LICENSE BLOCK *****
 | 
					# ***** BEGIN LICENSE BLOCK *****
 | 
				
			||||||
# This file is part of InDefero, an open source project management application.
 | 
					# This file is part of InDefero, an open source project management application.
 | 
				
			||||||
# Copyright (C) 2008 Céondo Ltd and contributors.
 | 
					# Copyright (C) 2008-2011 Céondo Ltd and contributors.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# InDefero is free software; you can redistribute it and/or modify
 | 
					# InDefero is free software; you can redistribute it and/or modify
 | 
				
			||||||
# it under the terms of the GNU General Public License as published by
 | 
					# it under the terms of the GNU General Public License as published by
 | 
				
			||||||
@@ -132,6 +132,46 @@ class IDF_Project extends Pluf_Model
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
        return $projects[0];
 | 
					        return $projects[0];
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Returns the number of open/closed issues.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param string Status ('open'), 'closed'
 | 
				
			||||||
 | 
					     * @param IDF_Tag Subfilter with a label (null)
 | 
				
			||||||
 | 
					     * @return int Count
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function getIssueCountByOwner($status='open')
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        switch ($status) {
 | 
				
			||||||
 | 
					        case 'open':
 | 
				
			||||||
 | 
					            $tags = implode(',', $this->getTagIdsByStatus('open'));
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        case 'closed':
 | 
				
			||||||
 | 
					        default:
 | 
				
			||||||
 | 
					            $tags = implode(',', $this->getTagIdsByStatus('closed'));
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        $sqlIssueTable = Pluf::factory('IDF_Issue')->getSqlTable();
 | 
				
			||||||
 | 
					        $query = "SELECT uid AS id,COUNT(uid) AS nb
 | 
				
			||||||
 | 
					FROM (
 | 
				
			||||||
 | 
					    SELECT COALESCE(owner, -1) AS uid
 | 
				
			||||||
 | 
					    FROM $sqlIssueTable
 | 
				
			||||||
 | 
					    WHERE status IN ($tags)
 | 
				
			||||||
 | 
					    ) AS ff
 | 
				
			||||||
 | 
					GROUP BY uid";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $db = Pluf::db();
 | 
				
			||||||
 | 
					        $dbData = $db->select($query);
 | 
				
			||||||
 | 
					        $ownerStatistics = array();
 | 
				
			||||||
 | 
					        foreach ($dbData as $k => $v) {
 | 
				
			||||||
 | 
					            $key = ($v['id'] === '-1') ? null : $v['id'];
 | 
				
			||||||
 | 
					            $ownerStatistics[$key] = (int)$v['nb'];
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        arsort($ownerStatistics);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $ownerStatistics;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Returns the number of open/closed issues.
 | 
					     * Returns the number of open/closed issues.
 | 
				
			||||||
@@ -233,6 +273,29 @@ class IDF_Project extends Pluf_Model
 | 
				
			|||||||
        return $tags;
 | 
					        return $tags;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Returns a list of relations which are available in this project as
 | 
				
			||||||
 | 
					     * associative array. Each key-value pair marks a set of orthogonal
 | 
				
			||||||
 | 
					     * relations. To ease processing, each of these pairs is included twice
 | 
				
			||||||
 | 
					     * in the array, once as key1 => key2 and once as key2 => key1.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return array List of relation names
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function getRelationsFromConfig()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $conf = $this->getConf();
 | 
				
			||||||
 | 
					        $rel = $conf->getVal('issue_relations', IDF_Form_IssueTrackingConf::init_relations);
 | 
				
			||||||
 | 
					        $relations = array();
 | 
				
			||||||
 | 
					        foreach (preg_split("/\015\012|\015|\012/", $rel, -1, PREG_SPLIT_NO_EMPTY) as $s) {
 | 
				
			||||||
 | 
					            $verbs = preg_split("/\s*,\s*/", $s, 2);
 | 
				
			||||||
 | 
					            if (count($verbs) == 1)
 | 
				
			||||||
 | 
					                $relations += array($verbs[0] => $verbs[0]);
 | 
				
			||||||
 | 
					            else
 | 
				
			||||||
 | 
					                $relations += array($verbs[0] => $verbs[1], $verbs[1] => $verbs[0]);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return $relations;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Return membership data.
 | 
					     * Return membership data.
 | 
				
			||||||
     *
 | 
					     *
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,7 +3,7 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
# ***** BEGIN LICENSE BLOCK *****
 | 
					# ***** BEGIN LICENSE BLOCK *****
 | 
				
			||||||
# This file is part of InDefero, an open source project management application.
 | 
					# This file is part of InDefero, an open source project management application.
 | 
				
			||||||
# Copyright (C) 2008 Céondo Ltd and contributors.
 | 
					# Copyright (C) 2008-2011 Céondo Ltd and contributors.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# InDefero is free software; you can redistribute it and/or modify
 | 
					# InDefero is free software; you can redistribute it and/or modify
 | 
				
			||||||
# it under the terms of the GNU General Public License as published by
 | 
					# it under the terms of the GNU General Public License as published by
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,7 +3,7 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
# ***** BEGIN LICENSE BLOCK *****
 | 
					# ***** BEGIN LICENSE BLOCK *****
 | 
				
			||||||
# This file is part of InDefero, an open source project management application.
 | 
					# This file is part of InDefero, an open source project management application.
 | 
				
			||||||
# Copyright (C) 2008 Céondo Ltd and contributors.
 | 
					# Copyright (C) 2008-2011 Céondo Ltd and contributors.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# InDefero is free software; you can redistribute it and/or modify
 | 
					# InDefero is free software; you can redistribute it and/or modify
 | 
				
			||||||
# it under the terms of the GNU General Public License as published by
 | 
					# it under the terms of the GNU General Public License as published by
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,7 +3,7 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
# ***** BEGIN LICENSE BLOCK *****
 | 
					# ***** BEGIN LICENSE BLOCK *****
 | 
				
			||||||
# This file is part of InDefero, an open source project management application.
 | 
					# This file is part of InDefero, an open source project management application.
 | 
				
			||||||
# Copyright (C) 2008 Céondo Ltd and contributors.
 | 
					# Copyright (C) 2008-2011 Céondo Ltd and contributors.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# InDefero is free software; you can redistribute it and/or modify
 | 
					# InDefero is free software; you can redistribute it and/or modify
 | 
				
			||||||
# it under the terms of the GNU General Public License as published by
 | 
					# it under the terms of the GNU General Public License as published by
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,7 +3,7 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
# ***** BEGIN LICENSE BLOCK *****
 | 
					# ***** BEGIN LICENSE BLOCK *****
 | 
				
			||||||
# This file is part of InDefero, an open source project management application.
 | 
					# This file is part of InDefero, an open source project management application.
 | 
				
			||||||
# Copyright (C) 2008 Céondo Ltd and contributors.
 | 
					# Copyright (C) 2008-2011 Céondo Ltd and contributors.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# InDefero is free software; you can redistribute it and/or modify
 | 
					# InDefero is free software; you can redistribute it and/or modify
 | 
				
			||||||
# it under the terms of the GNU General Public License as published by
 | 
					# it under the terms of the GNU General Public License as published by
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,7 +3,7 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
# ***** BEGIN LICENSE BLOCK *****
 | 
					# ***** BEGIN LICENSE BLOCK *****
 | 
				
			||||||
# This file is part of InDefero, an open source project management application.
 | 
					# This file is part of InDefero, an open source project management application.
 | 
				
			||||||
# Copyright (C) 2008 Céondo Ltd and contributors.
 | 
					# Copyright (C) 2008-2011 Céondo Ltd and contributors.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# InDefero is free software; you can redistribute it and/or modify
 | 
					# InDefero is free software; you can redistribute it and/or modify
 | 
				
			||||||
# it under the terms of the GNU General Public License as published by
 | 
					# it under the terms of the GNU General Public License as published by
 | 
				
			||||||
 
 | 
				
			|||||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user